- Linting... Prettier...
This commit is contained in:
77
.eslintrc.js
77
.eslintrc.js
@@ -1,4 +1,81 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
root: true,
|
root: true,
|
||||||
extends: '@react-native-community',
|
extends: '@react-native-community',
|
||||||
|
env: {
|
||||||
|
mocha: true,
|
||||||
|
browser: true,
|
||||||
|
},
|
||||||
|
// parser: 'babel-eslint',
|
||||||
|
// plugins: ['babel', 'immutablejs'],
|
||||||
|
plugins: ['immutablejs'],
|
||||||
|
rules: {
|
||||||
|
'comma-dangle': 'off',
|
||||||
|
'func-call-spacing': 'off',
|
||||||
|
'import/prefer-default-export': 'off',
|
||||||
|
'max-len': ['error', 150, { ignoreComments: true, ignoreTemplateLiterals: true }],
|
||||||
|
'no-confusing-arrow': 'off',
|
||||||
|
'no-mixed-operators': 'off',
|
||||||
|
'no-restricted-properties': [
|
||||||
|
2,
|
||||||
|
{
|
||||||
|
object: 'describe',
|
||||||
|
property: 'only',
|
||||||
|
message:
|
||||||
|
'Please remove any instance of .only from unit tests. If .only is required outside of a unit test, feel free to add an eslint override to ignore this instance of this error.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
object: 'it',
|
||||||
|
property: 'only',
|
||||||
|
message:
|
||||||
|
'Please remove any instance of .only from unit tests. If .only is required outside of a unit test, feel free to add an eslint override to ignore this instance of this error.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
object: 'context',
|
||||||
|
property: 'only',
|
||||||
|
message:
|
||||||
|
'Please remove any instance of .only from unit tests. If .only is required outside of a unit test, feel free to add an eslint override to ignore this instance of this error.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
object: 'tape',
|
||||||
|
property: 'only',
|
||||||
|
message:
|
||||||
|
'Please remove any instance of .only from unit tests. If .only is required outside of a unit test, feel free to add an eslint override to ignore this instance of this error.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
object: 'test',
|
||||||
|
property: 'only',
|
||||||
|
message:
|
||||||
|
'Please remove any instance of .only from unit tests. If .only is required outside of a unit test, feel free to add an eslint override to ignore this instance of this error.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
object: 'fixture',
|
||||||
|
property: 'only',
|
||||||
|
message:
|
||||||
|
'Please remove any instance of .only from unit tests. If .only is required outside of a unit test, feel free to add an eslint override to ignore this instance of this error.',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'no-spaced-func': 'off',
|
||||||
|
'react/jsx-closing-bracket-location': 'off',
|
||||||
|
'react/jsx-first-prop-new-line': 'off',
|
||||||
|
'react/jsx-no-literals': ['error', { noStrings: true }],
|
||||||
|
'react/jsx-no-target-blank': 'off',
|
||||||
|
'react/no-danger': 'off',
|
||||||
|
'space-before-function-paren': 'off',
|
||||||
|
indent: 'off',
|
||||||
|
'indent-legacy': 'off',
|
||||||
|
'immutablejs/no-native-map-set': 'error',
|
||||||
|
'no-invalid-this': 'off',
|
||||||
|
// 'babel/no-invalid-this': 'error',
|
||||||
|
},
|
||||||
|
overrides: [
|
||||||
|
{
|
||||||
|
files: ['lib/fixtures/**/*.js', '**/testHelper.js'],
|
||||||
|
rules: {
|
||||||
|
'import/no-extraneous-dependencies': ['error', { devDependencies: true }],
|
||||||
|
},
|
||||||
|
globals: {
|
||||||
|
expect: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
8
.prettierrc
Normal file
8
.prettierrc
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"arrowParens": "always",
|
||||||
|
"jsxBracketSameLine": false,
|
||||||
|
"singleQuote": true,
|
||||||
|
"tabWidth": 4,
|
||||||
|
"printWidth": 100,
|
||||||
|
"trailingComma": "all"
|
||||||
|
}
|
||||||
@@ -10,5 +10,5 @@ import App from '../App';
|
|||||||
import renderer from 'react-test-renderer';
|
import renderer from 'react-test-renderer';
|
||||||
|
|
||||||
it('renders correctly', () => {
|
it('renders correctly', () => {
|
||||||
renderer.create(<App />);
|
renderer.create(<App />);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,12 +1,3 @@
|
|||||||
/**
|
|
||||||
* Sample React Native App
|
|
||||||
* https://github.com/facebook/react-native
|
|
||||||
*
|
|
||||||
* @format
|
|
||||||
* @flow
|
|
||||||
*/
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import { createAppContainer } from 'react-navigation';
|
import { createAppContainer } from 'react-navigation';
|
||||||
|
|
||||||
import { Tabs } from './router.js';
|
import { Tabs } from './router.js';
|
||||||
|
|||||||
6
app/actions/activeEvent.js
Normal file
6
app/actions/activeEvent.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { SET_ACTIVE_EVENT } from '../constants/actionTypes.js';
|
||||||
|
|
||||||
|
export const setActiveEvent = (eventId) => ({
|
||||||
|
type: SET_ACTIVE_EVENT,
|
||||||
|
payload: eventId,
|
||||||
|
});
|
||||||
@@ -1,52 +1,54 @@
|
|||||||
import { blockUI, unblockUI } from './index.js';
|
import { placeBid as placeBidApi } from '../api/bid.js';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
BID_FAILURE,
|
BID_FAILURE,
|
||||||
BID_SUCCESS,
|
BID_SUCCESS,
|
||||||
PLACE_BID,
|
PLACE_BID,
|
||||||
SET_AUCTION_FILTER,
|
SET_AUCTION_FILTER,
|
||||||
SET_AUCTION_VIEW_MODE,
|
SET_AUCTION_VIEW_MODE,
|
||||||
} from '../constants/actionTypes.js';
|
} from '../constants/actionTypes.js';
|
||||||
|
import { getActiveEventId } from '../selectors/activeEvent.js';
|
||||||
|
import { getAuthToken } from '../selectors/auth.js';
|
||||||
|
|
||||||
const placeBidFailure = (bid, dispatch) => {
|
const placeBidFailure = (payload) => ({
|
||||||
dispatch({ type: BID_FAILURE, bid });
|
type: BID_FAILURE,
|
||||||
dispatch(unblockUI);
|
payload,
|
||||||
|
});
|
||||||
|
|
||||||
|
const placeBidSuccess = (payload) => ({
|
||||||
|
type: BID_SUCCESS,
|
||||||
|
payload,
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleBidFailure = (error) => (dispatch) => {
|
||||||
|
console.error('[postBid]', error);
|
||||||
|
dispatch(placeBidFailure(error));
|
||||||
};
|
};
|
||||||
|
|
||||||
const placeBidSuccess = (bid, dispatch) => {
|
const handleBidSuccess = (result) => (dispatch) => {
|
||||||
dispatch({ type: BID_SUCCESS, bid });
|
dispatch(placeBidSuccess(result));
|
||||||
dispatch(unblockUI);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const startPlacingBid = (itemId) => ({
|
||||||
|
type: PLACE_BID,
|
||||||
|
payload: itemId,
|
||||||
|
});
|
||||||
|
|
||||||
export const changeFilterMode = (payload) => ({
|
export const changeFilterMode = (payload) => ({
|
||||||
type: SET_AUCTION_FILTER,
|
type: SET_AUCTION_FILTER,
|
||||||
payload,
|
payload,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const changeViewMode = (payload) => ({
|
export const changeViewMode = (payload) => ({
|
||||||
type: SET_AUCTION_VIEW_MODE,
|
type: SET_AUCTION_VIEW_MODE,
|
||||||
payload,
|
payload,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const placeBid = (payload) => ({
|
export const placeBid = ({ bidAmount, itemId, maxAmount }) => (dispatch, getState) => {
|
||||||
type: PLACE_BID,
|
const authToken = getAuthToken(getState());
|
||||||
payload,
|
const eventId = getActiveEventId(getState());
|
||||||
});
|
|
||||||
|
|
||||||
export const postBid = () => (dispatch, getState) => {
|
dispatch(startPlacingBid(itemId));
|
||||||
const state = getState();
|
placeBidApi({ bidAmount, eventId, itemId, maxAmount }, authToken)
|
||||||
const activeEvent = state.get('activeEvent');
|
.then((payload) => dispatch(handleBidSuccess(payload)))
|
||||||
|
.catch((err) => dispatch(handleBidFailure(err)));
|
||||||
let apiUrl = getEndpointUrl(API_ENDPOINTS.GET_ITEMS);
|
|
||||||
apiUrl = apiUrl.replace(/:event_id$/, '');
|
|
||||||
if (activeEvent) {
|
|
||||||
apiUrl = `${apiUrl}${activeEvent}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch(blockUI());
|
|
||||||
|
|
||||||
fetch(apiUrl)
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(payload => itemsLoadSuccess(payload, dispatch))
|
|
||||||
.catch(err => console.error('[actions::getItems]', err));
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,39 +1,27 @@
|
|||||||
import { List } from 'immutable';
|
import { List } from 'immutable';
|
||||||
|
|
||||||
import { getEndpointUrl } from '../api/index.js';
|
import { fetchAuctionStatus as fetchActionStatusApi } from '../api/actionStatus.js';
|
||||||
|
import { AUCTIONS_UPDATED } from '../constants/actionTypes.js';
|
||||||
import {
|
import { getActiveEventId } from '../selectors/activeEvent.js';
|
||||||
AUCTIONS_UPDATED,
|
import { getAuthToken } from '../selectors/auth.js';
|
||||||
ITEMS_LOADED,
|
|
||||||
} from '../constants/actionTypes.js';
|
|
||||||
|
|
||||||
import { blockUI, unblockUI } from './index.js';
|
|
||||||
import { API_ENDPOINTS } from '../constants/constants.js';
|
|
||||||
|
|
||||||
import Auction from '../domain/Auction.js';
|
import Auction from '../domain/Auction.js';
|
||||||
|
|
||||||
|
const auctionsUpdated = (payload) => ({
|
||||||
|
type: AUCTIONS_UPDATED,
|
||||||
|
payload,
|
||||||
|
});
|
||||||
|
|
||||||
const autionStatusLoadSuccess = (auctions, dispatch) => {
|
const autionStatusLoadSuccess = (auctions) => (dispatch) => {
|
||||||
const payload = List(auctions).map((i) => Auction.fromJS(i));
|
const payload = List(auctions).map((i) => Auction.fromJS(i));
|
||||||
dispatch({ type: AUCTIONS_UPDATED, payload });
|
dispatch(auctionsUpdated(payload));
|
||||||
dispatch(unblockUI);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchAuctionStatus = () => (dispatch, getState) => {
|
export const fetchAuctionStatus = () => (dispatch, getState) => {
|
||||||
const state = getState();
|
const authToken = getAuthToken(getState());
|
||||||
const activeEvent = state.get('activeEvent');
|
const eventId = getActiveEventId(getState());
|
||||||
|
|
||||||
let apiUrl = getEndpointUrl(API_ENDPOINTS.GET_STATUS);
|
return fetchActionStatusApi(eventId, authToken)
|
||||||
apiUrl = apiUrl.replace(/:event_id$/, '');
|
.then((payload) => dispatch(autionStatusLoadSuccess(payload)))
|
||||||
if (activeEvent) {
|
.catch((err) => console.error('[actions::getStatus]', err));
|
||||||
apiUrl = `${apiUrl}${activeEvent}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch(blockUI());
|
|
||||||
|
|
||||||
return fetch(apiUrl)
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(payload => autionStatusLoadSuccess(payload, dispatch))
|
|
||||||
.catch(err => console.error('[actions::getStatus]', err));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,36 +1,31 @@
|
|||||||
import { List } from 'immutable';
|
import { List } from 'immutable';
|
||||||
|
|
||||||
import { blockUI, unblockUI } from './index.js';
|
|
||||||
import { fetchEvents as fetchEventsApi } from '../api/events.js';
|
import { fetchEvents as fetchEventsApi } from '../api/events.js';
|
||||||
import {
|
import { EVENTS_LOAD_FAILED, EVENTS_LOADED, GET_EVENTS } from '../constants/actionTypes.js';
|
||||||
EVENTS_LOAD_FAILED,
|
|
||||||
EVENTS_LOADED,
|
|
||||||
GET_EVENTS,
|
|
||||||
} from '../constants/actionTypes.js';
|
|
||||||
import Event from '../domain/Event.js';
|
import Event from '../domain/Event.js';
|
||||||
import { getAuthToken } from '../selectors/auth.js';
|
import { getAuthToken } from '../selectors/auth.js';
|
||||||
|
|
||||||
|
const beginFetchEvents = () => ({ type: GET_EVENTS });
|
||||||
|
|
||||||
const eventsLoaded = (payload) => ({ type: EVENTS_LOADED, payload });
|
const eventsLoaded = (payload) => ({ type: EVENTS_LOADED, payload });
|
||||||
|
|
||||||
const eventsLoadError = (payload) => ({ type: EVENTS_LOAD_FAILED, payload });
|
const eventsLoadError = (payload) => ({ type: EVENTS_LOAD_FAILED, payload });
|
||||||
|
|
||||||
const eventsFetchSuccess = (items) => (dispatch) => {
|
const eventsFetchSuccess = (items) => (dispatch) => {
|
||||||
const payload = List(items).map((i) => Event.fromJS(i));
|
const payload = List(items).map((i) => Event.fromJS(i));
|
||||||
|
dispatch(eventsLoaded(payload));
|
||||||
dispatch(eventsLoaded(payload));
|
|
||||||
dispatch(unblockUI);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const eventsFetchFailure = (error) => (dispatch) => {
|
const eventsFetchFailure = (error) => (dispatch) => {
|
||||||
console.error('[actions::events::eventsFetchFailure]', error);
|
console.error('[actions::events::eventsFetchFailure]', error);
|
||||||
dispatch(eventsLoadError(error));
|
dispatch(eventsLoadError(error));
|
||||||
dispatch(unblockUI);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchEvents = () => (dispatch, getState) => {
|
export const fetchEvents = () => (dispatch, getState) => {
|
||||||
const authToken = getAuthToken(getState());
|
const authToken = getAuthToken(getState());
|
||||||
|
|
||||||
fetchEventsApi(authToken)
|
dispatch(beginFetchEvents());
|
||||||
.then(payload => dispatch(eventsFetchSuccess(payload)))
|
fetchEventsApi(authToken)
|
||||||
.catch(err => dispatch(eventsFetchFailure(err)));
|
.then((payload) => dispatch(eventsFetchSuccess(payload)))
|
||||||
|
.catch((err) => dispatch(eventsFetchFailure(err)));
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
import {
|
import { BLOCK_UI, UNBLOCK_UI } from '../constants/actionTypes.js';
|
||||||
BLOCK_UI,
|
|
||||||
UNBLOCK_UI,
|
|
||||||
} from '../constants/actionTypes.js';
|
|
||||||
|
|
||||||
export const blockUI = () => ({
|
export const blockUI = () => ({
|
||||||
type: BLOCK_UI,
|
type: BLOCK_UI,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const unblockUI = () => ({
|
export const unblockUI = () => ({
|
||||||
type: UNBLOCK_UI,
|
type: UNBLOCK_UI,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,39 +1,34 @@
|
|||||||
import { List } from 'immutable';
|
import { List } from 'immutable';
|
||||||
|
|
||||||
import { fetchItems as fetchItemsApi } from '../api/items.js';
|
import { fetchItems as fetchItemsApi } from '../api/items.js';
|
||||||
import {
|
import { GET_ITEMS, ITEMS_LOAD_FAILED, ITEMS_LOADED } from '../constants/actionTypes.js';
|
||||||
GET_ITEMS,
|
|
||||||
ITEMS_LOADED,
|
|
||||||
} from '../constants/actionTypes.js';
|
|
||||||
import { getActiveEventId } from '../selectors/activeEvent.js';
|
import { getActiveEventId } from '../selectors/activeEvent.js';
|
||||||
import { getAuthToken } from '../selectors/auth.js';
|
import { getAuthToken } from '../selectors/auth.js';
|
||||||
|
|
||||||
import { blockUI, unblockUI } from './index.js';
|
|
||||||
|
|
||||||
import Item from '../domain/Item.js';
|
import Item from '../domain/Item.js';
|
||||||
|
|
||||||
|
const beginItemLoad = () => ({ type: GET_ITEMS });
|
||||||
|
|
||||||
const itemsLoaded = (payload) => ({ type: ITEMS_LOADED, payload });
|
const itemsLoaded = (payload) => ({ type: ITEMS_LOADED, payload });
|
||||||
|
|
||||||
const itemsLoadError = (payload) => ({ type: ITEMS_LOAD_FAILED, payload });
|
const itemsLoadFailure = (payload) => ({ type: ITEMS_LOAD_FAILED, payload });
|
||||||
|
|
||||||
const itemsFetchSuccess = (items) => (dispatch) => {
|
const itemsFetchSuccess = (items) => (dispatch) => {
|
||||||
const payload = List(items).map((i) => Item.fromJS(i));
|
const payload = List(items).map((i) => Item.fromJS(i));
|
||||||
|
dispatch(itemsLoaded(payload));
|
||||||
dispatch(itemsLoaded(payload));
|
|
||||||
dispatch(unblockUI);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const itemsFetchFailure = (error) => (dispatch) => {
|
const itemsFetchFailure = (error) => (dispatch) => {
|
||||||
console.error('[actions::items::itemsFetchFailure]', error);
|
console.error('[actions::items::itemsFetchFailure]', error);
|
||||||
dispatch(itemsLoadFailure(error));
|
dispatch(itemsLoadFailure(error));
|
||||||
dispatch(unblockUI);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchItems = () => (dispatch, getState) => {
|
export const fetchItems = () => (dispatch, getState) => {
|
||||||
const eventId = getActiveEventId(getState());
|
const authToken = getAuthToken(getState());
|
||||||
const authToken = getAuthToken(getState());
|
const eventId = getActiveEventId(getState());
|
||||||
|
|
||||||
fetchItemsApi(activeEvent, authToken)
|
dispatch(beginItemLoad());
|
||||||
.then(payload => dispatch(itemsFetchSuccess(payload)))
|
fetchItemsApi(eventId, authToken)
|
||||||
.catch(err => dispatch(itemsFetchFailure(err)));
|
.then((payload) => dispatch(itemsFetchSuccess(payload)))
|
||||||
|
.catch((err) => dispatch(itemsFetchFailure(err)));
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,124 +1,117 @@
|
|||||||
import { blockUI, unblockUI } from './index.js';
|
import { blockUI, unblockUI } from './index.js';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getEmailAvailability,
|
getEmailAvailability,
|
||||||
getNomAvailaibility,
|
getNomAvailaibility,
|
||||||
loginUser,
|
loginUser,
|
||||||
registerNewUser,
|
registerNewUser,
|
||||||
} from '../api/profile.js';
|
} from '../api/profile.js';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DO_LOGOUT,
|
DO_LOGOUT,
|
||||||
LOGIN_FAILURE,
|
LOGIN_FAILURE,
|
||||||
LOGIN_SUCCESS,
|
LOGIN_SUCCESS,
|
||||||
PROFILE_EMAIL_AVAILABLE,
|
PROFILE_EMAIL_AVAILABLE,
|
||||||
PROFILE_NOM_AVAILABLE,
|
PROFILE_NOM_AVAILABLE,
|
||||||
UNSET_AUTH,
|
REGISTRATION_FAILURE,
|
||||||
UNSET_PROFILE,
|
REGISTRATION_SUCCESS,
|
||||||
UPDATE_PROFILE,
|
UNSET_AUTH,
|
||||||
|
UNSET_PROFILE,
|
||||||
|
UPDATE_PROFILE,
|
||||||
} from '../constants/actionTypes.js';
|
} from '../constants/actionTypes.js';
|
||||||
|
|
||||||
const isValidEmail = (payload) => ({
|
const isValidEmail = (payload) => ({
|
||||||
type: PROFILE_EMAIL_AVAILABLE,
|
type: PROFILE_EMAIL_AVAILABLE,
|
||||||
payload,
|
payload,
|
||||||
});
|
});
|
||||||
|
|
||||||
const isValidNom = (payload) => ({
|
const isValidNom = (payload) => ({
|
||||||
type: PROFILE_NOM_AVAILABLE,
|
type: PROFILE_NOM_AVAILABLE,
|
||||||
payload,
|
payload,
|
||||||
});
|
});
|
||||||
|
|
||||||
const loginFailure = (payload) => ({
|
const loginFailure = (payload) => ({
|
||||||
type: LOGIN_FAILURE,
|
type: LOGIN_FAILURE,
|
||||||
payload,
|
payload,
|
||||||
});
|
});
|
||||||
|
|
||||||
const loginSuccess = (payload) => ({
|
const loginSuccess = (payload) => ({
|
||||||
type: LOGIN_SUCCESS,
|
type: LOGIN_SUCCESS,
|
||||||
payload,
|
payload,
|
||||||
});
|
});
|
||||||
|
|
||||||
const logoutUser = () => ({
|
const logoutUser = () => ({
|
||||||
type: DO_LOGOUT,
|
type: DO_LOGOUT,
|
||||||
});
|
});
|
||||||
|
|
||||||
const registrationFailure = (payload) => ({
|
const registrationFailure = (payload) => ({
|
||||||
type: REGISTRATION_FAILURE,
|
type: REGISTRATION_FAILURE,
|
||||||
payload,
|
payload,
|
||||||
});
|
});
|
||||||
|
|
||||||
const registrationSuccess = (payload) => ({
|
const registrationSuccess = (payload) => ({
|
||||||
type: REGISTRATION_SUCCESS,
|
type: REGISTRATION_SUCCESS,
|
||||||
payload,
|
payload,
|
||||||
});
|
});
|
||||||
|
|
||||||
const unsetAuth = () => ({
|
const unsetAuth = () => ({
|
||||||
type: UNSET_AUTH,
|
type: UNSET_AUTH,
|
||||||
});
|
});
|
||||||
|
|
||||||
const unsetProfile = () => ({
|
const unsetProfile = () => ({
|
||||||
type: UNSET_PROFILE,
|
type: UNSET_PROFILE,
|
||||||
});
|
});
|
||||||
|
|
||||||
const updateProfile = (profile) => ({
|
const updateProfile = (profile) => ({
|
||||||
type: UPDATE_PROFILE,
|
type: UPDATE_PROFILE,
|
||||||
payload: profile,
|
payload: profile,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const checkEmailAvailability = (email) => (dispatch) => {
|
export const checkEmailAvailability = (email) => (dispatch) => {};
|
||||||
|
|
||||||
};
|
export const checkNomAvailability = (nomDeBid) => (dispatch) => {};
|
||||||
|
|
||||||
export const checkNomAvailability = (nomDeBid) => (dispatch) => {
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
export const login = (username, password) => (dispatch) => {
|
export const login = (username, password) => (dispatch) => {
|
||||||
dispatch(blockUI());
|
dispatch(blockUI());
|
||||||
loginUser(username, password)
|
loginUser(username, password)
|
||||||
.then(result => {
|
.then((result) => {
|
||||||
dispatch(loginSuccess(result))
|
dispatch(loginSuccess(result));
|
||||||
})
|
})
|
||||||
.catch(err => dispatch(loginFailure(err)));
|
.catch((err) => dispatch(loginFailure(err)));
|
||||||
};
|
};
|
||||||
|
|
||||||
export const logout = () => (dispatch) => {
|
export const logout = () => (dispatch) => {
|
||||||
dispatch(unsetProfile());
|
dispatch(unsetProfile());
|
||||||
dispatch(unsetAuth());
|
dispatch(unsetAuth());
|
||||||
dispatch(logoutUser());
|
dispatch(logoutUser());
|
||||||
};
|
};
|
||||||
|
|
||||||
// USER REGISTRATION
|
// USER REGISTRATION
|
||||||
const handleRegistrationSuccess = (user) => (dispatch) => {
|
const handleRegistrationSuccess = (user) => (dispatch) => {
|
||||||
dispatch(unblockUI());
|
dispatch(unblockUI());
|
||||||
dispatch(registrationSuccess());
|
dispatch(registrationSuccess());
|
||||||
dispatch(loginSuccess(user));
|
dispatch(loginSuccess(user));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRegistrationFailure = (error) => (dispatch) => {
|
const handleRegistrationFailure = (error) => (dispatch) => {
|
||||||
dispatch(unblockUI());
|
dispatch(unblockUI());
|
||||||
dispatch(registrationFailure(error));
|
dispatch(registrationFailure(error));
|
||||||
};
|
};
|
||||||
|
|
||||||
export const registerUser = (user) => (dispatch) => {
|
export const registerUser = (user) => (dispatch) => {
|
||||||
dispatch(blockUI());
|
dispatch(blockUI());
|
||||||
registerNewUser(user)
|
registerNewUser(user)
|
||||||
.then(user => dispatch(handleRegistrationSuccess(user)))
|
.then((user) => dispatch(handleRegistrationSuccess(user)))
|
||||||
.catch(err => dispatch(handleRegistrationFailure(err)));
|
.catch((err) => dispatch(handleRegistrationFailure(err)));
|
||||||
};
|
};
|
||||||
|
|
||||||
// FACEBOOK
|
// FACEBOOK
|
||||||
export const facebookLoginSuccess = (result) => (dispatch) => {
|
export const facebookLoginSuccess = (result) => (dispatch) => {
|
||||||
console.log('facebookLoginSuccess', result);
|
console.log('facebookLoginSuccess', result);
|
||||||
dispatch(facebookLoginSuccess(result));
|
dispatch(facebookLoginSuccess(result));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// LOGIN SERVICES COMMON ACTIONS
|
// LOGIN SERVICES COMMON ACTIONS
|
||||||
export const serviceRegistrationError = (error) => (dispatch) => {
|
export const serviceRegistrationError = (error) => (dispatch) => {};
|
||||||
|
|
||||||
};
|
export const serviceRegistrationCanceled = () => (dispatch) => {};
|
||||||
|
|
||||||
export const serviceRegistrationCanceled = () => (dispatch) => {
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|||||||
7
app/api/auctionStatus.js
Normal file
7
app/api/auctionStatus.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import { API_ENDPOINTS, requestGet } from './index.js';
|
||||||
|
|
||||||
|
export const fetchAuctionStatus = (eventId, auth) => {
|
||||||
|
const path = `${API_ENDPOINTS.GET_STATUS})/${eventId}`;
|
||||||
|
const opts = { Authorization: auth ? `Bearer ${auth}` : null };
|
||||||
|
return requestGet(path, null, opts);
|
||||||
|
};
|
||||||
10
app/api/bid.js
Normal file
10
app/api/bid.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { API_ENDPOINTS, requestPost } from './index.js';
|
||||||
|
|
||||||
|
export const placeBid = ({ bidAmount, bidderId, eventId, itemId, maxAmount }, auth) => {
|
||||||
|
const requestOptions = { Authorization: auth ? `Bearer ${auth}` : null };
|
||||||
|
return requestPost({
|
||||||
|
path: `${API_ENDPOINTS.PLACE_BID}/${itemId}`,
|
||||||
|
body: { bidAmount, bidderId, eventId, maxAmount },
|
||||||
|
requestOptions,
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { API_ENDPOINTS, requestGet } from './index.js';
|
import { API_ENDPOINTS, requestGet } from './index.js';
|
||||||
|
|
||||||
export const fetchEvents = (auth) => {
|
export const fetchEvents = (auth) => {
|
||||||
const opts = { Authorization: auth ? `Bearer ${auth}` : null };
|
const opts = { Authorization: auth ? `Bearer ${auth}` : null };
|
||||||
return requestGet(API_ENDPOINTS.GET_EVENTS, null, opts);
|
return requestGet(API_ENDPOINTS.GET_EVENTS, null, opts);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,21 +1,23 @@
|
|||||||
import { API_URL } from '../constants/constants.js';
|
import { API_URL } from '../constants/constants.js';
|
||||||
|
|
||||||
export const constructUrl = (path, params, host = API_URL) => {
|
export const constructUrl = (path, params, host = API_URL) => {
|
||||||
if (!(/^\//g).test(path)) {
|
if (!/^\//g.test(path)) {
|
||||||
throw new Error(`Invalid path! Expecting a valid relative path (path needs to start with /)(${path})`);
|
throw new Error(
|
||||||
}
|
`Invalid path! Expecting a valid relative path (path needs to start with /)(${path})`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let url = path;
|
let url = path;
|
||||||
|
|
||||||
if (host) {
|
if (host) {
|
||||||
url = `${host}${url}`;
|
url = `${host}${url}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params) {
|
if (params) {
|
||||||
url = `${url}?${params}`;
|
url = `${url}?${params}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return url;
|
return url;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -26,59 +28,57 @@ export const constructUrl = (path, params, host = API_URL) => {
|
|||||||
* this serializes data in a way that helps support legacy endpoints
|
* this serializes data in a way that helps support legacy endpoints
|
||||||
*/
|
*/
|
||||||
export const formatPostData = (body) => {
|
export const formatPostData = (body) => {
|
||||||
const postData = new FormData();
|
const postData = new FormData();
|
||||||
Object.keys(body).forEach(key => postData.append(key, body[key]));
|
Object.keys(body).forEach((key) => postData.append(key, body[key]));
|
||||||
return postData;
|
return postData;
|
||||||
};
|
};
|
||||||
|
|
||||||
const parseQueryParamsString = (queryParams) => {
|
const parseQueryParamsString = (queryParams) => {
|
||||||
if (typeof queryParams !== 'string') {
|
if (typeof queryParams !== 'string') {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return queryParams;
|
return queryParams;
|
||||||
};
|
};
|
||||||
|
|
||||||
const parseQueryParamsObject = (queryParams) => {
|
const parseQueryParamsObject = (queryParams) => {
|
||||||
if (queryParams === null || typeof queryParams !== 'object' || Array.isArray(queryParams)) {
|
if (queryParams === null || typeof queryParams !== 'object' || Array.isArray(queryParams)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Object
|
return Object.keys(queryParams)
|
||||||
.keys(queryParams)
|
.map((key) => {
|
||||||
.map((key) => {
|
const value = queryParams[key];
|
||||||
const value = queryParams[key];
|
return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
|
||||||
return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
|
})
|
||||||
})
|
.join('&');
|
||||||
.join('&');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const parseQueryParamsArray = (queryParams) => {
|
const parseQueryParamsArray = (queryParams) => {
|
||||||
if (!Array.isArray(queryParams)) {
|
if (!Array.isArray(queryParams)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return queryParams
|
return queryParams
|
||||||
.map((param) => {
|
.map((param) => {
|
||||||
const [key, value] = param.split('=');
|
const [key, value] = param.split('=');
|
||||||
return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
|
return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
|
||||||
})
|
})
|
||||||
.join('&');
|
.join('&');
|
||||||
};
|
};
|
||||||
|
|
||||||
export const parseQueryParams = queryParams => (
|
export const parseQueryParams = (queryParams) =>
|
||||||
parseQueryParamsString(queryParams) ||
|
parseQueryParamsString(queryParams) ||
|
||||||
parseQueryParamsObject(queryParams) ||
|
parseQueryParamsObject(queryParams) ||
|
||||||
parseQueryParamsArray(queryParams) ||
|
parseQueryParamsArray(queryParams) ||
|
||||||
''
|
'';
|
||||||
);
|
|
||||||
|
|
||||||
export const request = (url, options) => {
|
export const request = (url, options) => {
|
||||||
try {
|
try {
|
||||||
return fetch(url, options).catch((err) => console.error(err));
|
return fetch(url, options).catch((err) => console.error(err));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const unwrapJson = (response) => response.json();
|
export const unwrapJson = (response) => response.json();
|
||||||
|
|||||||
126
app/api/index.js
126
app/api/index.js
@@ -1,95 +1,95 @@
|
|||||||
import {
|
import {
|
||||||
constructUrl,
|
constructUrl,
|
||||||
formatPostData,
|
formatPostData,
|
||||||
parseQueryParams,
|
parseQueryParams,
|
||||||
request,
|
request,
|
||||||
unwrapJson,
|
unwrapJson,
|
||||||
validateResponse,
|
validateResponse,
|
||||||
} from './helpers.js';
|
} from './helpers.js';
|
||||||
|
|
||||||
import { API_URL } from '../constants/constants.js';
|
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',
|
||||||
GET_ITEMS: '/items',
|
GET_ITEMS: '/items',
|
||||||
|
|
||||||
// Auction Interactions
|
// Auction Interactions
|
||||||
// GET_STATUS: '/auction/:event_id',
|
// GET_STATUS: '/auction/:event_id',
|
||||||
GET_STATUS: '/auction',
|
GET_STATUS: '/auction',
|
||||||
PLACE_BID: '/bids/:item_id',
|
PLACE_BID: '/bids',
|
||||||
PURCHASE_ITEM: '/sales',
|
PURCHASE_ITEM: '/sales',
|
||||||
|
|
||||||
// User/Profile
|
// User/Profile
|
||||||
USER_SIGNUP: '/signup',
|
USER_SIGNUP: '/signup',
|
||||||
USER_PROFILE: '/users/:user_id',
|
USER_PROFILE: '/users/:user_id',
|
||||||
|
|
||||||
VALIDATE_SIGNUP_EMAIL: '/signup/validate/email',
|
VALIDATE_SIGNUP_EMAIL: '/signup/validate/email',
|
||||||
VALIDATE_SIGNUP_NOM: '/signup/validate/nom',
|
VALIDATE_SIGNUP_NOM: '/signup/validate/nom',
|
||||||
|
|
||||||
// Services
|
// Services
|
||||||
APPLE_SIGNUP: '/auth/apple/login',
|
APPLE_SIGNUP: '/auth/apple/login',
|
||||||
APPLE_LINK: '/auth/apple/link',
|
APPLE_LINK: '/auth/apple/link',
|
||||||
FACEBOOK_SIGNUP: '/auth/facebook/login',
|
FACEBOOK_SIGNUP: '/auth/facebook/login',
|
||||||
FACEBOOK_LINK: '/auth/facebook/link',
|
FACEBOOK_LINK: '/auth/facebook/link',
|
||||||
GOOGLE_SIGNUP: '/auth/google/login',
|
GOOGLE_SIGNUP: '/auth/google/login',
|
||||||
GOOGLE_LINK: '/auth/google/link',
|
GOOGLE_LINK: '/auth/google/link',
|
||||||
};
|
};
|
||||||
|
|
||||||
const cacheBuster = () => {
|
const cacheBuster = () => {
|
||||||
const timestamp = String(Date.now());
|
const timestamp = String(Date.now());
|
||||||
return `?buster=${timestamp}`;
|
return `?buster=${timestamp}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getEndpointUrl = (endpoint) => {
|
export const getEndpointUrl = (endpoint) => {
|
||||||
if (!endpoints[endpoint]) {
|
if (!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}${endpoints[endpoint]}`; //`${cacheBuster()}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const requestGet = (path, queryParams = [], requestOptions = {}) => {
|
export const requestGet = (path, queryParams = [], requestOptions = {}) => {
|
||||||
const params = parseQueryParams(queryParams);
|
const params = parseQueryParams(queryParams);
|
||||||
|
|
||||||
if (params === null) {
|
if (params === null) {
|
||||||
throw new Error('Invalid queryParams');
|
throw new Error('Invalid queryParams');
|
||||||
}
|
}
|
||||||
|
|
||||||
return request(constructUrl(path, params), {
|
return request(constructUrl(path, params), {
|
||||||
...DefaultRequestOptions,
|
...DefaultRequestOptions,
|
||||||
...requestOptions
|
...requestOptions,
|
||||||
})
|
})
|
||||||
.then(validateResponse)
|
.then(validateResponse)
|
||||||
.then(unwrapJson);
|
.then(unwrapJson);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const requestPost = (options) => {
|
export const requestPost = (options) => {
|
||||||
const {
|
const {
|
||||||
path,
|
path,
|
||||||
body = {},
|
body = {},
|
||||||
queryParams = [],
|
queryParams = [],
|
||||||
requestOptions = {},
|
requestOptions = {},
|
||||||
isFormattedPostData = false
|
isFormattedPostData = false,
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
const params = parseQueryParams(queryParams || []);
|
const params = parseQueryParams(queryParams || []);
|
||||||
|
|
||||||
if (params === null) {
|
if (params === null) {
|
||||||
throw new Error('invalid queryParams');
|
throw new Error('invalid queryParams');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Additional formatting happens in `formatPostData()`
|
// Additional formatting happens in `formatPostData()`
|
||||||
// like handling what jQuery calls `traditional` form data
|
// like handling what jQuery calls `traditional` form data
|
||||||
return request(constructUrl(path, params), {
|
return request(constructUrl(path, params), {
|
||||||
...DefaultRequestOptions,
|
...DefaultRequestOptions,
|
||||||
...requestOptions,
|
...requestOptions,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: isFormattedPostData ? body : formatPostData(body)
|
body: isFormattedPostData ? body : formatPostData(body),
|
||||||
})
|
})
|
||||||
.then(validateResponse)
|
.then(validateResponse)
|
||||||
.then(unwrapJson);
|
.then(unwrapJson);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { API_ENDPOINTS, 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);
|
||||||
const opts = { Authorization: auth ? `Bearer ${auth}` : null };
|
const opts = { Authorization: auth ? `Bearer ${auth}` : null };
|
||||||
return requestGet(path, null, opts);
|
return requestGet(path, null, opts);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,15 +1,19 @@
|
|||||||
import { API_ENDPOINTS, requestGet } from './index.js';
|
import { API_ENDPOINTS, requestGet } from './index.js';
|
||||||
|
|
||||||
export const getEmailAvailability = (email) => requestGet(`${API_ENDPOINTS.VALIDATE_SIGNUP_EMAIL}/&{encodeURI(email)}`);
|
export const getEmailAvailability = (email) =>
|
||||||
|
requestGet(`${API_ENDPOINTS.VALIDATE_SIGNUP_EMAIL}/&{encodeURI(email)}`);
|
||||||
|
|
||||||
export const getNomAvailaibility = (nomDeBid) => requestGet(`${API_ENDPOINTS.VALIDATE_SIGNUP_NOM}/${encodeURI(nomDeBid)}`);
|
export const getNomAvailaibility = (nomDeBid) =>
|
||||||
|
requestGet(`${API_ENDPOINTS.VALIDATE_SIGNUP_NOM}/${encodeURI(nomDeBid)}`);
|
||||||
|
|
||||||
export const loginUser = (username, password) => requestPost({
|
export const loginUser = (username, password) =>
|
||||||
path: API_ENDPOINTS.LOGIN,
|
requestPost({
|
||||||
body: { username, password },
|
path: API_ENDPOINTS.LOGIN,
|
||||||
});
|
body: { username, password },
|
||||||
|
});
|
||||||
|
|
||||||
export const registerNewUser = (user) => requestPost({
|
export const registerNewUser = (user) =>
|
||||||
path: API_ENDPOINTS.USER_SIGNUP,
|
requestPost({
|
||||||
body: { user },
|
path: API_ENDPOINTS.USER_SIGNUP,
|
||||||
});
|
body: { user },
|
||||||
|
});
|
||||||
|
|||||||
@@ -5,7 +5,10 @@ import { fetchEvents } from '../../actions/events.js';
|
|||||||
import AppHeader from './AppHeader.js';
|
import AppHeader from './AppHeader.js';
|
||||||
|
|
||||||
const matchDispatchToProps = (dispatch) => ({
|
const matchDispatchToProps = (dispatch) => ({
|
||||||
fetchEvents: () => dispatch(fetchEvents()),
|
fetchEvents: () => dispatch(fetchEvents()),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(null, matchDispatchToProps)(AppHeader);
|
export default connect(
|
||||||
|
null,
|
||||||
|
matchDispatchToProps,
|
||||||
|
)(AppHeader);
|
||||||
|
|||||||
@@ -10,27 +10,26 @@ import HeaderContentRight from './HeaderContentRight.container.js';
|
|||||||
import styles from './AppHeader.styles.js';
|
import styles from './AppHeader.styles.js';
|
||||||
|
|
||||||
export default class AppHeader extends Component {
|
export default class AppHeader extends Component {
|
||||||
|
static get propTypes() {
|
||||||
|
return {
|
||||||
|
fetchEvents: PropTypes.func.isRequired,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
static get propTypes() {
|
componentDidMount() {
|
||||||
return {
|
this.props.fetchEvents();
|
||||||
fetchEvents: PropTypes.func.isRequired,
|
}
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
render() {
|
||||||
this.props.fetchEvents();
|
const { navigation } = this.props;
|
||||||
}
|
|
||||||
|
|
||||||
render () {
|
return (
|
||||||
const { navigation } = this.props;
|
<Header
|
||||||
|
placement="left"
|
||||||
return (
|
leftComponent={<HeaderContentRight navigation={navigation} />}
|
||||||
<Header
|
centerComponent={<HeaderTitle navigation={navigation} />}
|
||||||
placement="left"
|
rightComponent={<HeaderContentLeft navigation={navigation} />}
|
||||||
leftComponent={<HeaderContentRight navigation={navigation} />}
|
/>
|
||||||
centerComponent={<HeaderTitle navigation={navigation} />}
|
);
|
||||||
rightComponent={<HeaderContentLeft navigation={navigation} />}
|
}
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,12 +5,15 @@ import { hasMultipleEvents } from '../../selectors/events.js';
|
|||||||
import HeaderContentLeft from './HeaderContentLeft.js';
|
import HeaderContentLeft from './HeaderContentLeft.js';
|
||||||
|
|
||||||
const matchStateToProps = (state, ownProps) => {
|
const matchStateToProps = (state, ownProps) => {
|
||||||
const { routeName } = ownProps.navigation.state;
|
const { routeName } = ownProps.navigation.state;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
activeRoute: routeName,
|
activeRoute: routeName,
|
||||||
hasMultipleEvents: hasMultipleEvents(state),
|
hasMultipleEvents: hasMultipleEvents(state),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(matchStateToProps, null)(HeaderContentLeft);
|
export default connect(
|
||||||
|
matchStateToProps,
|
||||||
|
null,
|
||||||
|
)(HeaderContentLeft);
|
||||||
|
|||||||
@@ -1,53 +1,43 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import {
|
import { Text, TouchableOpacity, View } from 'react-native';
|
||||||
Text,
|
|
||||||
TouchableOpacity,
|
|
||||||
View,
|
|
||||||
} from 'react-native';
|
|
||||||
|
|
||||||
import BackIcon from './IconButtons/BackIcon.js';
|
import BackIcon from './IconButtons/BackIcon.js';
|
||||||
import EventsIcon from './IconButtons/EventsIcon.js';
|
import EventsIcon from './IconButtons/EventsIcon.js';
|
||||||
|
|
||||||
export default function HeaderContentLeft({
|
export default function HeaderContentLeft({ activeRoute, hasMultipleEvents, navigation }) {
|
||||||
activeRoute,
|
const _goBack = () => {
|
||||||
hasMultipleEvents,
|
if (hasActiveEvent) {
|
||||||
navigation,
|
navigation.goBack();
|
||||||
}) {
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const _goBack = () => {
|
console.log('nowhere to go...');
|
||||||
if (hasActiveEvent) {
|
};
|
||||||
navigation.goBack();
|
|
||||||
return false;
|
const _showEvents = () => {
|
||||||
|
navigation.navigate('Events');
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (activeRoute === 'Events') {
|
||||||
|
return <EventsIcon action={_goBack} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('nowhere to go...');
|
if (activeRoute === 'Profile') {
|
||||||
};
|
return <BackIcon action={_goBack} />;
|
||||||
|
}
|
||||||
|
|
||||||
const _showEvents = () => {
|
return <EventsIcon action={hasMultipleEvents ? _showEvents : null} />;
|
||||||
navigation.navigate('Events');
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
if (activeRoute === 'Events') {
|
|
||||||
return <EventsIcon action={_goBack} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (activeRoute === 'Profile') {
|
|
||||||
return <BackIcon action={_goBack} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return <EventsIcon action={hasMultipleEvents ? _showEvents : null} />
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HeaderContentLeft.propTypes = {
|
HeaderContentLeft.propTypes = {
|
||||||
activeRoute: PropTypes.string.isRequired,
|
activeRoute: PropTypes.string.isRequired,
|
||||||
hasActiveEvent: PropTypes.bool,
|
hasActiveEvent: PropTypes.bool,
|
||||||
navigation: PropTypes.func.isRequired,
|
navigation: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
HeaderContentLeft.defaultProps = {
|
HeaderContentLeft.defaultProps = {
|
||||||
hasActiveEvent: false,
|
hasActiveEvent: false,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,8 +5,11 @@ import { getProfileAvatarUrl } from '../../selectors/profile.js';
|
|||||||
import HeaderContentRight from './HeaderContentRight.js';
|
import HeaderContentRight from './HeaderContentRight.js';
|
||||||
|
|
||||||
const matchStateToProps = (state, ownProps) => ({
|
const matchStateToProps = (state, ownProps) => ({
|
||||||
avatarUrl: getProfileAvatarUrl(state),
|
avatarUrl: getProfileAvatarUrl(state),
|
||||||
hideUserProfileButton: ownProps.navigation.state.routeName === 'Profile',
|
hideUserProfileButton: ownProps.navigation.state.routeName === 'Profile',
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(matchStateToProps, null)(HeaderContentRight);
|
export default connect(
|
||||||
|
matchStateToProps,
|
||||||
|
null,
|
||||||
|
)(HeaderContentRight);
|
||||||
|
|||||||
@@ -4,14 +4,13 @@ import PropTypes from 'prop-types';
|
|||||||
import UserProfileButton from './UserProfileButton/UserProfileButton.container.js';
|
import UserProfileButton from './UserProfileButton/UserProfileButton.container.js';
|
||||||
|
|
||||||
export default function HeaderContentRight({ hideUserProfileButton, navigation }) {
|
export default function HeaderContentRight({ hideUserProfileButton, navigation }) {
|
||||||
|
if (hideUserProfileButton) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (hideUserProfileButton) {
|
return <UserProfileButton />;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return <UserProfileButton />;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HeaderContentRight.propTypes = {
|
HeaderContentRight.propTypes = {
|
||||||
hideUserProfileButton: PropTypes.bool.isRequired,
|
hideUserProfileButton: PropTypes.bool.isRequired,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,14 +5,17 @@ import { getActiveEvent, getDefaultEvent } from '../../../../selectors/events.js
|
|||||||
import EventTitle from './EventTitle.js';
|
import EventTitle from './EventTitle.js';
|
||||||
|
|
||||||
const matchStateToProps = (state) => {
|
const matchStateToProps = (state) => {
|
||||||
const event = hasActiveEvent(state) ? getActiveEvent(state) : getDefaultEvent(state);
|
const event = hasActiveEvent(state) ? getActiveEvent(state) : getDefaultEvent(state);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
date: event.get('date'),
|
date: event.get('date'),
|
||||||
end: event.get('end'),
|
end: event.get('end'),
|
||||||
name: event.get('name'),
|
name: event.get('name'),
|
||||||
start: event.get('start'),
|
start: event.get('start'),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(matchStateToProps, null)(EventTitle);
|
export default connect(
|
||||||
|
matchStateToProps,
|
||||||
|
null,
|
||||||
|
)(EventTitle);
|
||||||
|
|||||||
@@ -1,43 +1,33 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import {
|
import { Text, TouchableOpacity, View } from 'react-native';
|
||||||
Text,
|
|
||||||
TouchableOpacity,
|
|
||||||
View,
|
|
||||||
} from 'react-native';
|
|
||||||
|
|
||||||
import styles from './EventTitle.styles.js';
|
import styles from './EventTitle.styles.js';
|
||||||
|
|
||||||
export default function EventTitle({
|
export default function EventTitle({ action, date, end, name, start }) {
|
||||||
action,
|
const _generateEventTitle = () => (
|
||||||
date,
|
<View style={styles.eventInfo}>
|
||||||
end,
|
<Text style={styles.eventName}>{name}</Text>
|
||||||
name,
|
<Text style={styles.eventDate}>{`${date} | ${start} - ${end}`}</Text>
|
||||||
start,
|
</View>
|
||||||
}) {
|
);
|
||||||
const _generateEventTitle = () => (
|
|
||||||
<View style={styles.eventInfo}>
|
|
||||||
<Text style={styles.eventName}>{name}</Text>
|
|
||||||
<Text style={styles.eventDate}>{`${date} | ${start} - ${end}`}</Text>
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
|
|
||||||
if (action) {
|
if (action) {
|
||||||
return <TouchableOpacity onPress={action}>{_generateEventTitle()}</TouchableOpacity>;
|
return <TouchableOpacity onPress={action}>{_generateEventTitle()}</TouchableOpacity>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _generateEventTitle();
|
return _generateEventTitle();
|
||||||
}
|
}
|
||||||
|
|
||||||
EventTitle.propTypes = {
|
EventTitle.propTypes = {
|
||||||
action: PropTypes.func,
|
action: PropTypes.func,
|
||||||
date: PropTypes.string.isRequired,
|
date: PropTypes.string.isRequired,
|
||||||
end: PropTypes.string.isRequired,
|
end: PropTypes.string.isRequired,
|
||||||
name: PropTypes.string.isRequired,
|
name: PropTypes.string.isRequired,
|
||||||
start: PropTypes.string.isRequired,
|
start: PropTypes.string.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
EventTitle.defaultProps = {
|
EventTitle.defaultProps = {
|
||||||
action: null,
|
action: null,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import { StyleSheet } from 'react-native';
|
import { StyleSheet } from 'react-native';
|
||||||
|
|
||||||
export const styles = StyleSheet.create({
|
export default (styles = StyleSheet.create({
|
||||||
eventInfo: {
|
eventInfo: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
},
|
},
|
||||||
eventName: {
|
eventName: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
},
|
},
|
||||||
eventDate: {
|
eventDate: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
},
|
},
|
||||||
});
|
}));
|
||||||
|
|||||||
@@ -6,13 +6,16 @@ import { hasMultipleEvents } from '../../../selectors/events.js';
|
|||||||
import HeaderTitle from './HeaderTitle.js';
|
import HeaderTitle from './HeaderTitle.js';
|
||||||
|
|
||||||
const matchStateToProps = (state, ownProps) => {
|
const matchStateToProps = (state, ownProps) => {
|
||||||
const { routeName } = ownProps.navigation.state;
|
const { routeName } = ownProps.navigation.state;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
activeRoute: routeName,
|
activeRoute: routeName,
|
||||||
hasActiveEvent: hasActiveEvent(state),
|
hasActiveEvent: hasActiveEvent(state),
|
||||||
hasMultipleEvents: hasMultipleEvents(state),
|
hasMultipleEvents: hasMultipleEvents(state),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(matchStateToProps, null)(HeaderTitle);
|
export default connect(
|
||||||
|
matchStateToProps,
|
||||||
|
null,
|
||||||
|
)(HeaderTitle);
|
||||||
|
|||||||
@@ -1,60 +1,54 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import {
|
import { Text, TouchableOpacity, View } from 'react-native';
|
||||||
Text,
|
|
||||||
TouchableOpacity,
|
|
||||||
View,
|
|
||||||
} from 'react-native';
|
|
||||||
|
|
||||||
import EventTitle from './EventTitle/EventTitle.container.js';
|
import EventTitle from './EventTitle/EventTitle.container.js';
|
||||||
|
|
||||||
import styles from './HeaderTitle.styles.js';
|
import styles from './HeaderTitle.styles.js';
|
||||||
|
|
||||||
export default function HeaderTitle({
|
export default function HeaderTitle({
|
||||||
activeRoute,
|
activeRoute,
|
||||||
hasActiveEvent,
|
hasActiveEvent,
|
||||||
hasMultipleEvents,
|
hasMultipleEvents,
|
||||||
navigation,
|
navigation,
|
||||||
}) {
|
}) {
|
||||||
|
const _goBack = () => {
|
||||||
|
if (hasActiveEvent) {
|
||||||
|
navigation.goBack();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const _goBack = () => {
|
console.log('nowhere to go...');
|
||||||
if (hasActiveEvent) {
|
};
|
||||||
navigation.goBack();
|
|
||||||
return false;
|
const _showEvents = () => {
|
||||||
|
navigation.navigate('Events');
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (activeRoute === 'Events') {
|
||||||
|
return (
|
||||||
|
<TouchableOpacity onPress={_goBack}>
|
||||||
|
<Text style={styles.screenHeader}>Profile</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('nowhere to go...');
|
if (activeRoute === 'Profile') {
|
||||||
};
|
return <Text style={styles.screenHeader}>Profile</Text>;
|
||||||
|
}
|
||||||
|
|
||||||
const _showEvents = () => {
|
return <EventTitle action={hasMultipleEvents ? _showEvents : null} />;
|
||||||
navigation.navigate('Events');
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
if (activeRoute === 'Events') {
|
|
||||||
return (
|
|
||||||
<TouchableOpacity onPress={_goBack}>
|
|
||||||
<Text style={styles.screenHeader}>Profile</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (activeRoute === 'Profile') {
|
|
||||||
return <Text style={styles.screenHeader}>Profile</Text>;
|
|
||||||
}
|
|
||||||
|
|
||||||
return <EventTitle action={hasMultipleEvents ? _showEvents : null} />
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HeaderTitle.propTypes = {
|
HeaderTitle.propTypes = {
|
||||||
activeRoute: PropTypes.string.isRequired,
|
activeRoute: PropTypes.string.isRequired,
|
||||||
hasActiveEvent: PropTypes.bool,
|
hasActiveEvent: PropTypes.bool,
|
||||||
hasMultipleEvents: PropTypes.bool.isRequired,
|
hasMultipleEvents: PropTypes.bool.isRequired,
|
||||||
navigation: PropTypes.func.isRequired,
|
navigation: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
HeaderTitle.defaultProps = {
|
HeaderTitle.defaultProps = {
|
||||||
hasActiveEvent: false,
|
hasActiveEvent: false,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
import { StyleSheet } from 'react-native';
|
import { StyleSheet } from 'react-native';
|
||||||
|
|
||||||
export const styles = StyleSheet.create({
|
export default (styles = StyleSheet.create({
|
||||||
filterBar: {
|
filterBar: {
|
||||||
backgroundColor: '#0F0',
|
backgroundColor: '#0F0',
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
},
|
},
|
||||||
filter: {
|
filter: {
|
||||||
flex: 2,
|
flex: 2,
|
||||||
},
|
},
|
||||||
view: {
|
view: {
|
||||||
flex: 2,
|
flex: 2,
|
||||||
},
|
},
|
||||||
});
|
}));
|
||||||
|
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ 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 }) {
|
||||||
return (
|
return (
|
||||||
<TouchableOpacity onPress={action}>
|
<TouchableOpacity onPress={action}>
|
||||||
<Icon name="ei-chevron-left" type="evilicons" size={28} />;
|
<Icon name="ei-chevron-left" type="evilicons" size={28} />;
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
BackIcon.propTypes = {
|
BackIcon.propTypes = {
|
||||||
action: PropTypes.func.isRequired,
|
action: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,20 +5,19 @@ import { TouchableOpacity } from 'react-native';
|
|||||||
import { Icon } from 'react-native-elements';
|
import { Icon } from 'react-native-elements';
|
||||||
|
|
||||||
export default function EventsIcon({ action }) {
|
export default function EventsIcon({ action }) {
|
||||||
|
const renderEventsIcon = () => <Icon name="ei-calendar" type="evilicons" size={28} />;
|
||||||
|
|
||||||
const renderEventsIcon = () => <Icon name="ei-calendar" type="evilicons" size={28} />;
|
if (action) {
|
||||||
|
return <TouchableOpacity onPress={action}>{renderEventsIcon()}</TouchableOpacity>;
|
||||||
|
}
|
||||||
|
|
||||||
if (action) {
|
return renderEventsIcon();
|
||||||
return <TouchableOpacity onPress={action}>{renderEventsIcon()}</TouchableOpacity>;
|
|
||||||
}
|
|
||||||
|
|
||||||
return renderEventsIcon();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EventsIcon.propTypes = {
|
EventsIcon.propTypes = {
|
||||||
action: PropTypes.func,
|
action: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
|
||||||
EventsIcon.defaultProps = {
|
EventsIcon.defaultProps = {
|
||||||
action: null,
|
action: null,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,7 +5,10 @@ import { getProfileAvatarUrl } from '../../../selectors/profile.js';
|
|||||||
import UserProfileButton from './UserProfileButton.js';
|
import UserProfileButton from './UserProfileButton.js';
|
||||||
|
|
||||||
const matchStateToProps = (state) => ({
|
const matchStateToProps = (state) => ({
|
||||||
avatarUrl: getProfileAvatarUrl(state),
|
avatarUrl: getProfileAvatarUrl(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(matchStateToProps, null)(UserProfileButton);
|
export default connect(
|
||||||
|
matchStateToProps,
|
||||||
|
null,
|
||||||
|
)(UserProfileButton);
|
||||||
|
|||||||
@@ -7,29 +7,28 @@ import { Icon } from 'react-native-elements';
|
|||||||
import styles from './UserProfileButton.styles.js';
|
import styles from './UserProfileButton.styles.js';
|
||||||
|
|
||||||
export default function UserProfileButton({ avatarUrl, navigation }) {
|
export default function UserProfileButton({ avatarUrl, navigation }) {
|
||||||
|
const _goToProfile = () => {
|
||||||
|
navigation.navigate('Profile');
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
const _goToProfile = () => {
|
return (
|
||||||
navigation.navigate('Profile');
|
<TouchableOpacity onPress={_goToProfile}>
|
||||||
return false;
|
{avatarUrl !== null ? (
|
||||||
};
|
<View style={styles.avatarWrap}>
|
||||||
|
<Image source={{ uri: avatarUrl }} />
|
||||||
return (
|
</View>
|
||||||
<TouchableOpacity onPress={_goToProfile}>
|
) : (
|
||||||
{avatarUrl !== null ? (
|
<Icon name="ei-user" type="evilicons" size={28} />
|
||||||
<View style={styles.avatarWrap}>
|
)}
|
||||||
<Image source={{ uri: avatarUrl }} />
|
</TouchableOpacity>
|
||||||
</View>
|
);
|
||||||
) : (
|
|
||||||
<Icon name="ei-user" type="evilicons" size={28} />
|
|
||||||
)}
|
|
||||||
</TouchableOpacity>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UserProfileButton.propTypes = {
|
UserProfileButton.propTypes = {
|
||||||
avatarUrl: PropTypes.string,
|
avatarUrl: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
UserProfileButton.propTypes = {
|
UserProfileButton.propTypes = {
|
||||||
avatarUrl: null,
|
avatarUrl: null,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,13 +1,7 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import {
|
import { StyleSheet, TouchableOpacity, Text, Image, View } from 'react-native';
|
||||||
StyleSheet,
|
|
||||||
TouchableOpacity,
|
|
||||||
Text,
|
|
||||||
Image,
|
|
||||||
View
|
|
||||||
} from 'react-native';
|
|
||||||
|
|
||||||
import GallerySwiper from 'react-native-gallery-swiper';
|
import GallerySwiper from 'react-native-gallery-swiper';
|
||||||
|
|
||||||
@@ -18,173 +12,173 @@ import { ITEM_TYPES } from '../../constants/constants.js';
|
|||||||
import { formatPrice, getAuctionTime } from '../../library/helpers.js';
|
import { formatPrice, getAuctionTime } from '../../library/helpers.js';
|
||||||
|
|
||||||
export default class AuctionListItem extends Component {
|
export default class AuctionListItem extends Component {
|
||||||
static get propTypes() {
|
static get propTypes() {
|
||||||
return {
|
return {
|
||||||
description: PropTypes.string,
|
description: PropTypes.string,
|
||||||
donor: PropTypes.string,
|
donor: PropTypes.string,
|
||||||
end: PropTypes.string.isRequired,
|
end: PropTypes.string.isRequired,
|
||||||
id: PropTypes.string.isRequired,
|
id: PropTypes.string.isRequired,
|
||||||
images: PropTypes.arrayOf(
|
images: PropTypes.arrayOf(
|
||||||
PropTypes.shape({
|
PropTypes.shape({
|
||||||
url: PropTypes.string,
|
url: PropTypes.string,
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
start: PropTypes.string.isRequired,
|
start: PropTypes.string.isRequired,
|
||||||
startingPrice: PropTypes.number.isRequired,
|
startingPrice: PropTypes.number.isRequired,
|
||||||
subtitle: PropTypes.string,
|
subtitle: PropTypes.string,
|
||||||
title: PropTypes.string.isRequired,
|
title: PropTypes.string.isRequired,
|
||||||
type: PropTypes.string.isRequired,
|
type: PropTypes.string.isRequired,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static get defaultProps() {
|
||||||
|
return {
|
||||||
|
description: null,
|
||||||
|
donor: null,
|
||||||
|
images: null,
|
||||||
|
subtitle: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
_getBidTime = () => {
|
||||||
|
const { end, start } = this.props;
|
||||||
|
return getAuctionTime({ end, start });
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
static get defaultProps() {
|
_viewItemDetail = () => {
|
||||||
return {
|
const { _id: id } = this.props.details;
|
||||||
description: null,
|
this.props.navigation.navigate('Item', { id });
|
||||||
donor: null,
|
|
||||||
images: null,
|
|
||||||
subtitle: null,
|
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
constructor(props) {
|
render() {
|
||||||
super(props);
|
const {
|
||||||
}
|
description,
|
||||||
|
donor,
|
||||||
|
end,
|
||||||
|
id,
|
||||||
|
images,
|
||||||
|
start,
|
||||||
|
startingPrice,
|
||||||
|
subtitle,
|
||||||
|
title,
|
||||||
|
type,
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
_getBidTime = () => {
|
return (
|
||||||
const { end, start } = this.props;
|
<TouchableOpacity onPress={this._viewItemDetail}>
|
||||||
return getAuctionTime({ end, start });
|
<View style={styles.rowContainer}>
|
||||||
}
|
{images !== null && images.length > 0 && (
|
||||||
|
<GallerySwiper
|
||||||
_viewItemDetail = () => {
|
enableScale={false}
|
||||||
const { _id: id } = this.props.details;
|
images={images}
|
||||||
this.props.navigation.navigate('Item', { id });
|
initialNumToRender={2}
|
||||||
}
|
resizeMode="cover"
|
||||||
|
sensitiveScroll={false}
|
||||||
render() {
|
style={{ height: 280 }}
|
||||||
const {
|
/>
|
||||||
description,
|
)}
|
||||||
donor,
|
<View style={styles.rowText}>
|
||||||
end,
|
{type === ITEM_TYPES.AUCTION && <BidStatus itemId={id} />}
|
||||||
id,
|
<Text style={styles.title} numberOfLines={2} ellipsizeMode={'tail'}>
|
||||||
images,
|
{title}
|
||||||
start,
|
</Text>
|
||||||
startingPrice,
|
<Text style={styles.subtitle} numberOfLines={1} ellipsizeMode={'tail'}>
|
||||||
subtitle,
|
{subtitle}
|
||||||
title,
|
</Text>
|
||||||
type,
|
{donor && (
|
||||||
} = this.props;
|
<Text style={styles.donor} numberOfLines={1} ellipsizeMode={'tail'}>
|
||||||
|
{donor}
|
||||||
return(
|
</Text>
|
||||||
<TouchableOpacity onPress={this._viewItemDetail}>
|
)}
|
||||||
<View style={styles.rowContainer}>
|
{type === ITEM_TYPES.AUCTION ? (
|
||||||
{images !== null && images.length > 0 && (
|
<AuctionPriceAndBidCount itemId={id} />
|
||||||
<GallerySwiper
|
) : (
|
||||||
enableScale={false}
|
<Text style={styles.price} numberOfLines={1} ellipsizeMode={'tail'}>
|
||||||
images={images}
|
{formatPrice(startingPrice)}
|
||||||
initialNumToRender={2}
|
</Text>
|
||||||
resizeMode="cover"
|
)}
|
||||||
sensitiveScroll={false}
|
<Text style={styles.timeline} numberOfLines={1}>
|
||||||
style={{height: 280}}
|
{this._getBidTime()}
|
||||||
/>
|
</Text>
|
||||||
)}
|
<Text style={styles.description} numberOfLines={3} ellipsizeMode={'tail'}>
|
||||||
<View style={styles.rowText}>
|
{description}
|
||||||
{type === ITEM_TYPES.AUCTION && <BidStatus itemId={id} />}
|
</Text>
|
||||||
<Text style={styles.title} numberOfLines={2} ellipsizeMode={'tail'}>
|
</View>
|
||||||
{title}
|
</View>
|
||||||
</Text>
|
</TouchableOpacity>
|
||||||
<Text style={styles.subtitle} numberOfLines={1} ellipsizeMode={'tail'}>
|
);
|
||||||
{subtitle}
|
}
|
||||||
</Text>
|
|
||||||
{donor && (
|
|
||||||
<Text style={styles.donor} numberOfLines={1} ellipsizeMode={'tail'}>
|
|
||||||
{donor}
|
|
||||||
</Text>
|
|
||||||
)}
|
|
||||||
{type === ITEM_TYPES.AUCTION ? (
|
|
||||||
<AuctionPriceAndBidCount itemId={id} />
|
|
||||||
) : (
|
|
||||||
<Text style={styles.price} numberOfLines={1} ellipsizeMode={'tail'}>
|
|
||||||
{formatPrice(startingPrice)}
|
|
||||||
</Text>
|
|
||||||
)}
|
|
||||||
<Text style={styles.timeline} numberOfLines={1}>
|
|
||||||
{this._getBidTime()}
|
|
||||||
</Text>
|
|
||||||
<Text style={styles.description} numberOfLines={3} ellipsizeMode={'tail'}>
|
|
||||||
{description}
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
</TouchableOpacity>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
description: {
|
description: {
|
||||||
color: '#777',
|
color: '#777',
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
marginTop: 5,
|
marginTop: 5,
|
||||||
paddingLeft: 10,
|
paddingLeft: 10,
|
||||||
paddingRight: 10,
|
paddingRight: 10,
|
||||||
},
|
},
|
||||||
donor: {
|
donor: {
|
||||||
color: '#777',
|
color: '#777',
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
marginTop: 5,
|
marginTop: 5,
|
||||||
paddingLeft: 10,
|
paddingLeft: 10,
|
||||||
},
|
},
|
||||||
image: {
|
image: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
height: undefined,
|
height: undefined,
|
||||||
width: undefined,
|
width: undefined,
|
||||||
},
|
},
|
||||||
price: {
|
price: {
|
||||||
color: '#777',
|
color: '#777',
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
paddingLeft: 10,
|
paddingLeft: 10,
|
||||||
paddingTop: 5,
|
paddingTop: 5,
|
||||||
},
|
},
|
||||||
rowContainer: {
|
rowContainer: {
|
||||||
backgroundColor: '#FFF',
|
backgroundColor: '#FFF',
|
||||||
borderRadius: 4,
|
borderRadius: 4,
|
||||||
flex: 1,
|
flex: 1,
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
marginRight: 10,
|
marginRight: 10,
|
||||||
marginLeft: 10,
|
marginLeft: 10,
|
||||||
marginTop: 10,
|
marginTop: 10,
|
||||||
padding: 10,
|
padding: 10,
|
||||||
shadowColor: '#CCC',
|
shadowColor: '#CCC',
|
||||||
shadowOffset: {
|
shadowOffset: {
|
||||||
width: 1,
|
width: 1,
|
||||||
height: 1
|
height: 1,
|
||||||
|
},
|
||||||
|
shadowOpacity: 1.0,
|
||||||
|
shadowRadius: 1,
|
||||||
|
},
|
||||||
|
rowText: {
|
||||||
|
flex: 4,
|
||||||
|
flexDirection: 'column',
|
||||||
|
},
|
||||||
|
subtitle: {
|
||||||
|
color: '#777',
|
||||||
|
fontSize: 14,
|
||||||
|
marginTop: 5,
|
||||||
|
paddingLeft: 10,
|
||||||
|
},
|
||||||
|
timeline: {
|
||||||
|
color: '#777',
|
||||||
|
fontSize: 14,
|
||||||
|
marginTop: 5,
|
||||||
|
paddingLeft: 10,
|
||||||
|
paddingRight: 10,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
color: '#777',
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
paddingLeft: 10,
|
||||||
|
paddingTop: 5,
|
||||||
},
|
},
|
||||||
shadowOpacity: 1.0,
|
|
||||||
shadowRadius: 1,
|
|
||||||
},
|
|
||||||
rowText: {
|
|
||||||
flex: 4,
|
|
||||||
flexDirection: 'column',
|
|
||||||
},
|
|
||||||
subtitle: {
|
|
||||||
color: '#777',
|
|
||||||
fontSize: 14,
|
|
||||||
marginTop: 5,
|
|
||||||
paddingLeft: 10,
|
|
||||||
},
|
|
||||||
timeline: {
|
|
||||||
color: '#777',
|
|
||||||
fontSize: 14,
|
|
||||||
marginTop: 5,
|
|
||||||
paddingLeft: 10,
|
|
||||||
paddingRight: 10,
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
color: '#777',
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: 'bold',
|
|
||||||
paddingLeft: 10,
|
|
||||||
paddingTop: 5,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,29 +3,26 @@ import PropTypes from 'prop-types';
|
|||||||
|
|
||||||
import { formatPrice } from '../../library/helpers.js';
|
import { formatPrice } from '../../library/helpers.js';
|
||||||
|
|
||||||
import {
|
import { StyleSheet, Text } from 'react-native';
|
||||||
StyleSheet,
|
|
||||||
Text,
|
|
||||||
} from 'react-native';
|
|
||||||
|
|
||||||
const AuctionPriceAndBidCount = ({ bidCount, currentPrice }) => {
|
const AuctionPriceAndBidCount = ({ bidCount, currentPrice }) => {
|
||||||
return (
|
return (
|
||||||
<Text style={styles.currentPriceAndBidCount} numberOfLines={1}>
|
<Text style={styles.currentPriceAndBidCount} numberOfLines={1}>
|
||||||
{`${formatPrice(currentPrice)} (${bidCount} bids)`}
|
{`${formatPrice(currentPrice)} (${bidCount} bids)`}
|
||||||
</Text>
|
</Text>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
AuctionPriceAndBidCount.propTypes = {
|
AuctionPriceAndBidCount.propTypes = {
|
||||||
itemId: PropTypes.string.isRequired,
|
itemId: PropTypes.string.isRequired,
|
||||||
bidCount: PropTypes.number.isRequired,
|
bidCount: PropTypes.number.isRequired,
|
||||||
currentPrice: PropTypes.number.isRequired,
|
currentPrice: PropTypes.number.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
currentPriceAndBidCount: {
|
currentPriceAndBidCount: {
|
||||||
color: '#000',
|
color: '#000',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default AuctionPriceAndBidCount;
|
export default AuctionPriceAndBidCount;
|
||||||
|
|||||||
@@ -1,44 +1,41 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import {
|
import { StyleSheet, Text } from 'react-native';
|
||||||
StyleSheet,
|
|
||||||
Text,
|
|
||||||
} from 'react-native';
|
|
||||||
|
|
||||||
const BidStatus = ({ isBidding, isWinning }) => {
|
const BidStatus = ({ isBidding, isWinning }) => {
|
||||||
if (!isBidding) {
|
if (!isBidding) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const statusBarStyle = isWinning
|
const statusBarStyle = isWinning
|
||||||
? [ styles.bidStatus, styes.isWinning ]
|
? [styles.bidStatus, styes.isWinning]
|
||||||
: [ styles.bidStatus, styles.isOutbid ];
|
: [styles.bidStatus, styles.isOutbid];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Text style={statusBarStyle} numberOfLines={1}>
|
<Text style={statusBarStyle} numberOfLines={1}>
|
||||||
{isWinning && `Oh no! You have been outbid!`}
|
{isWinning && 'Oh no! You have been outbid!'}
|
||||||
{!isWinning && isBidding && `You have the winning bid! (for now...)`}
|
{!isWinning && isBidding && 'You have the winning bid! (for now...)'}
|
||||||
</Text>
|
</Text>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
BidStatus.propTypes = {
|
BidStatus.propTypes = {
|
||||||
isBidding: PropTypes.bool.isRequired,
|
isBidding: PropTypes.bool.isRequired,
|
||||||
isWinning: PropTypes.bool.isRequired,
|
isWinning: PropTypes.bool.isRequired,
|
||||||
itemId: PropTypes.string.isRequired,
|
itemId: PropTypes.string.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
bidStatus: {
|
bidStatus: {
|
||||||
color: '#fff',
|
color: '#fff',
|
||||||
},
|
},
|
||||||
isWinning: {
|
isWinning: {
|
||||||
backgroundColor: '#F00',
|
backgroundColor: '#F00',
|
||||||
},
|
},
|
||||||
isOutbid: {
|
isOutbid: {
|
||||||
backgroundColor: '#0F0',
|
backgroundColor: '#0F0',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default BidStatus;
|
export default BidStatus;
|
||||||
|
|||||||
@@ -1,42 +1,38 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import {
|
import { StyleSheet, Text, View } from 'react-native';
|
||||||
StyleSheet,
|
|
||||||
Text,
|
|
||||||
View,
|
|
||||||
} from 'react-native';
|
|
||||||
|
|
||||||
const FilterBar = ({ changeFilterer, changeViewMode, filterMode, viewMode }) => (
|
const FilterBar = ({ changeFilterer, changeViewMode, filterMode, viewMode }) => (
|
||||||
<View style={styles.filterBar}>
|
<View style={styles.filterBar}>
|
||||||
<Text style={styles.filter}>Filter</Text>
|
<Text style={styles.filter}>Filter</Text>
|
||||||
<Text style={styles.view}>View</Text>
|
<Text style={styles.view}>View</Text>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
|
||||||
FilterBar.propTypes = {
|
FilterBar.propTypes = {
|
||||||
changeFilterer: PropTypes.func.isRequired,
|
changeFilterer: PropTypes.func.isRequired,
|
||||||
changeViewMode: PropTypes.func.isRequired,
|
changeViewMode: PropTypes.func.isRequired,
|
||||||
filterMode: PropTypes.string,
|
filterMode: PropTypes.string,
|
||||||
viewMode: PropTypes.string,
|
viewMode: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterBar.defaultProps = {
|
FilterBar.defaultProps = {
|
||||||
filterMode: null,
|
filterMode: null,
|
||||||
viewMode: null,
|
viewMode: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
filterBar: {
|
filterBar: {
|
||||||
backgroundColor: '#0F0',
|
backgroundColor: '#0F0',
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
},
|
},
|
||||||
filter: {
|
filter: {
|
||||||
flex: 2,
|
flex: 2,
|
||||||
},
|
},
|
||||||
view: {
|
view: {
|
||||||
flex: 2,
|
flex: 2,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default FilterBar;
|
export default FilterBar;
|
||||||
|
|||||||
@@ -1,84 +1,79 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import {
|
import { StyleSheet, TouchableOpacity, Text, Image, View } from 'react-native';
|
||||||
StyleSheet,
|
|
||||||
TouchableOpacity,
|
|
||||||
Text,
|
|
||||||
Image,
|
|
||||||
View
|
|
||||||
} from 'react-native';
|
|
||||||
|
|
||||||
export default class EventListItem extends Component {
|
export default class EventListItem extends Component {
|
||||||
static get propTypes() {
|
static get propTypes() {
|
||||||
return {
|
return {
|
||||||
description: PropTypes.string.isRequired,
|
end: PropTypes.string.isRequired,
|
||||||
endTime: PropTypes.string.isRequired,
|
id: PropTypes.string.isRequired,
|
||||||
id: PropTypes.string.isRequired,
|
images: PropTypes.arrayOf(
|
||||||
images: PropTypes.arrayOf(
|
PropTypes.shape({
|
||||||
PropTypes.shape({
|
url: PropTypes.string,
|
||||||
url: PropTypes.string,
|
}),
|
||||||
}),
|
),
|
||||||
),
|
setActiveEvent: PropTypes.func.isRequired,
|
||||||
isTicketed: PropTypes.bool,
|
showFrom: PropTypes.string.isRequired,
|
||||||
postCount: PropTypes.number,
|
showUntil: PropTypes.string.isRequired,
|
||||||
setActiveEvent: PropTypes.func.isRequired,
|
start: PropTypes.string.isRequired,
|
||||||
showFrom: PropTypes.string.isRequired,
|
tagline: PropTypes.string,
|
||||||
showUntil: PropTypes.string.isRequired,
|
name: PropTypes.string.isRequired,
|
||||||
startTime: PropTypes.string.isRequired,
|
};
|
||||||
tagline: PropTypes.string,
|
}
|
||||||
title: PropTypes.string.isRequired,
|
|
||||||
|
static get defaultProps() {
|
||||||
|
return {
|
||||||
|
images: null,
|
||||||
|
isTicketed: false,
|
||||||
|
postCount: 0,
|
||||||
|
tagline: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
_viewEventDetail = () => {
|
||||||
|
this.props.setActiveEvent(this.props.id);
|
||||||
|
this.props.navigation.navigate('Event');
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
static get defaultProps() {
|
render() {
|
||||||
return {
|
const { date, description, end, name, start } = this.props;
|
||||||
images: null,
|
|
||||||
isTicketed: false,
|
|
||||||
postCount: 0,
|
|
||||||
tagline: null,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(props) {
|
return (
|
||||||
super(props);
|
<TouchableOpacity onPress={this._viewEventDetail}>
|
||||||
}
|
<View style={styles.rowContainer}>
|
||||||
|
<Text>{name}</Text>
|
||||||
_viewEventDetail = () => {
|
<Text>{date}</Text>
|
||||||
const { id } = this.props.details;
|
<Text>
|
||||||
this.props.setActiveEvent(id);
|
{start} - {end}
|
||||||
this.props.navigation.navigate('Event');
|
</Text>
|
||||||
}
|
<Text>{description}</Text>
|
||||||
|
</View>
|
||||||
render() {
|
</TouchableOpacity>
|
||||||
const {
|
);
|
||||||
} = this.props;
|
}
|
||||||
|
|
||||||
return(
|
|
||||||
<TouchableOpacity onPress={this._viewEventDetail}>
|
|
||||||
<View style={styles.rowContainer}>
|
|
||||||
</View>
|
|
||||||
</TouchableOpacity>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
rowContainer: {
|
rowContainer: {
|
||||||
backgroundColor: '#FFF',
|
backgroundColor: '#FFF',
|
||||||
borderRadius: 4,
|
borderRadius: 4,
|
||||||
flex: 1,
|
flex: 1,
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
marginRight: 10,
|
marginRight: 10,
|
||||||
marginLeft: 10,
|
marginLeft: 10,
|
||||||
marginTop: 10,
|
marginTop: 10,
|
||||||
padding: 10,
|
padding: 10,
|
||||||
shadowColor: '#CCC',
|
shadowColor: '#CCC',
|
||||||
shadowOffset: {
|
shadowOffset: {
|
||||||
width: 1,
|
width: 1,
|
||||||
height: 1
|
height: 1,
|
||||||
|
},
|
||||||
|
shadowOpacity: 1.0,
|
||||||
|
shadowRadius: 1,
|
||||||
},
|
},
|
||||||
shadowOpacity: 1.0,
|
|
||||||
shadowRadius: 1,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,19 +1,22 @@
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
facebookLoginSuccess,
|
facebookLoginSuccess,
|
||||||
logout,
|
logout,
|
||||||
registrationServiceError,
|
registrationServiceError,
|
||||||
userCanceledRegistration,
|
userCanceledRegistration,
|
||||||
} from '../../actions/profile.js';
|
} from '../../actions/profile.js';
|
||||||
|
|
||||||
import FacebookLogin from './FacebookLogin.js';
|
import FacebookLogin from './FacebookLogin.js';
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
doCancelAction: () => dispatch(userCanceledRegistration()),
|
doCancelAction: () => dispatch(userCanceledRegistration()),
|
||||||
doErrorAction: (error) => dispatch(registrationServiceError(error)),
|
doErrorAction: (error) => dispatch(registrationServiceError(error)),
|
||||||
doLogoutAction: () => dispatch(logout()),
|
doLogoutAction: () => dispatch(logout()),
|
||||||
doSuccessAction: (result) => dispatch(facebookLoginSuccess(result)),
|
doSuccessAction: (result) => dispatch(facebookLoginSuccess(result)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(null, mapDispatchToProps)(FacebookLogin);
|
export default connect(
|
||||||
|
null,
|
||||||
|
mapDispatchToProps,
|
||||||
|
)(FacebookLogin);
|
||||||
|
|||||||
@@ -6,36 +6,33 @@ import { LoginButton } from 'react-native-fbsdk';
|
|||||||
import { PERMISSIONS } from '../../constants/constants.js';
|
import { PERMISSIONS } from '../../constants/constants.js';
|
||||||
|
|
||||||
export default function FacebookLogin({
|
export default function FacebookLogin({
|
||||||
doCancelAction,
|
doCancelAction,
|
||||||
doErrorAction,
|
doErrorAction,
|
||||||
doLogoutAction,
|
doLogoutAction,
|
||||||
doSuccessAction,
|
doSuccessAction,
|
||||||
}) {
|
}) {
|
||||||
|
return (
|
||||||
return (
|
<View>
|
||||||
<View>
|
<LoginButton
|
||||||
<LoginButton
|
publishPermissions={PERMISSIONS.FACEBOOK}
|
||||||
publishPermissions={PERMISSIONS.FACEBOOK}
|
onLoginFinished={(error, result) => {
|
||||||
onLoginFinished={
|
if (error) {
|
||||||
(error, result) => {
|
doErrorAction(error);
|
||||||
if (error) {
|
} else if (result.isCancelled) {
|
||||||
doErrorAction(error);
|
doCancelAction();
|
||||||
} else if (result.isCancelled) {
|
} else {
|
||||||
doCancelAction();
|
doSuccessAction(result);
|
||||||
} else {
|
}
|
||||||
doSuccessAction(result);
|
}}
|
||||||
}
|
onLogoutFinished={doLogoutAction}
|
||||||
}
|
/>
|
||||||
}
|
</View>
|
||||||
onLogoutFinished={doLogoutAction}
|
);
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FacebookLogin.propTypes = {
|
FacebookLogin.propTypes = {
|
||||||
doCancelAction: PropTypes.func.isRequired,
|
doCancelAction: PropTypes.func.isRequired,
|
||||||
doErrorAction: PropTypes.func.isRequired,
|
doErrorAction: PropTypes.func.isRequired,
|
||||||
doLogoutAction: PropTypes.func.isRequired,
|
doLogoutAction: PropTypes.func.isRequired,
|
||||||
doSuccessAction: PropTypes.func.isRequired,
|
doSuccessAction: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,7 +5,10 @@ import { login } from '../../actions/profile.js';
|
|||||||
import LocalLogin from './LocalLogin.js';
|
import LocalLogin from './LocalLogin.js';
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
doLoginAction: (username, password) => dispatch(login(username, password)),
|
doLoginAction: (username, password) => dispatch(login(username, password)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(null, mapDispatchToProps)(LocalLogin);
|
export default connect(
|
||||||
|
null,
|
||||||
|
mapDispatchToProps,
|
||||||
|
)(LocalLogin);
|
||||||
|
|||||||
@@ -4,52 +4,47 @@ import PropTypes from 'prop-types';
|
|||||||
import { Button, TextInput, View } from 'react-native';
|
import { Button, TextInput, View } from 'react-native';
|
||||||
|
|
||||||
export default function LocalLogin({ doLoginAction }) {
|
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 _handleLoginSubmit = () => {
|
||||||
const [ password, setPassword ] = useState(null);
|
doLoginAction(username, password);
|
||||||
const [ username, setUsername ] = useState(null);
|
};
|
||||||
|
|
||||||
const _handleLoginSubmit = () => {
|
const _updateState = (field, value) => {
|
||||||
doLoginAction(username, password);
|
if (field === 'username') {
|
||||||
};
|
setUsername(value);
|
||||||
|
}
|
||||||
|
|
||||||
const _updateState = (field, value) => {
|
if (field === 'password') {
|
||||||
if (field === 'username') {
|
setPassword(value);
|
||||||
setUsername(value);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (field === 'password') {
|
if (!!username && !!password) {
|
||||||
setPassword(value);
|
setEnableSubmit(true);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (!!username && !!password) {
|
return (
|
||||||
setEnableSubmit(true);
|
<View style={styles.loginWrap}>
|
||||||
}
|
<TextInput
|
||||||
};
|
style={{ height: 40 }}
|
||||||
|
placeholder="email"
|
||||||
return (
|
onChangeText={(text) => _updateState('username', text)}
|
||||||
<View style={styles.loginWrap}>
|
value={username}
|
||||||
<TextInput
|
/>
|
||||||
style={{height: 40}}
|
<TextInput
|
||||||
placeholder="email"
|
style={{ height: 40 }}
|
||||||
onChangeText={(text) => _updateState('username', text)}
|
placeholder="password"
|
||||||
value={username}
|
onChangeText={(text) => _updateState('password', text)}
|
||||||
/>
|
value={password}
|
||||||
<TextInput
|
/>
|
||||||
style={{height: 40}}
|
<Button disabled={!enabled} onPress={_handleLoginSubmit} title="Login" />
|
||||||
placeholder="password"
|
</View>
|
||||||
onChangeText={(text) => _updateState('password', text)}
|
);
|
||||||
value={password}
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
disabled={!enabled}
|
|
||||||
onPress={_handleLoginSubmit}
|
|
||||||
title="Login"
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalLogin.propTypes = {
|
LocalLogin.propTypes = {
|
||||||
doLoginAction: PropTypes.func.isRequired,
|
doLoginAction: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,53 +1,53 @@
|
|||||||
export const ITEM_FILTERS = {
|
export const ITEM_FILTERS = {
|
||||||
ALL: 'ALL',
|
ALL: 'ALL',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ITEM_TYPES = {
|
export const ITEM_TYPES = {
|
||||||
AUCTION: 'auction',
|
AUCTION: 'auction',
|
||||||
DONATION: 'donation',
|
DONATION: 'donation',
|
||||||
EVENT: 'event',
|
EVENT: 'event',
|
||||||
MEMBERSHIP: 'membership',
|
MEMBERSHIP: 'membership',
|
||||||
POPUP: 'popup',
|
POPUP: 'popup',
|
||||||
RAFFLE: 'raffle',
|
RAFFLE: 'raffle',
|
||||||
TICKET: 'ticket',
|
TICKET: 'ticket',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SORT_MODES = {
|
export const SORT_MODES = {
|
||||||
BIDDERS_ASC: 'BIDDERS_ASC',
|
BIDDERS_ASC: 'BIDDERS_ASC',
|
||||||
BIDDERS_DSC: 'BIDDERS_DSC',
|
BIDDERS_DSC: 'BIDDERS_DSC',
|
||||||
ENDING_ASC: 'ENDING_ASC',
|
ENDING_ASC: 'ENDING_ASC',
|
||||||
ENDING_DSC: 'ENDING_DSC',
|
ENDING_DSC: 'ENDING_DSC',
|
||||||
PRICE_ASC: 'PRICE_ASC',
|
PRICE_ASC: 'PRICE_ASC',
|
||||||
PRICE_DSC: 'PRICE_DSC',
|
PRICE_DSC: 'PRICE_DSC',
|
||||||
TITLE_ASC: 'TITLE_ASC',
|
TITLE_ASC: 'TITLE_ASC',
|
||||||
TITLE_DSC: 'TITLE_DSC',
|
TITLE_DSC: 'TITLE_DSC',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const AUCTION_VIEW_MODES = {
|
export const AUCTION_VIEW_MODES = {
|
||||||
ALL: 'ALL',
|
ALL: 'ALL',
|
||||||
BIDDING: 'BIDDING',
|
BIDDING: 'BIDDING',
|
||||||
NO_BIDS: 'NO_BIDS',
|
NO_BIDS: 'NO_BIDS',
|
||||||
WINNING: 'WINNING',
|
WINNING: 'WINNING',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const API_URL = 'http://localhost:3001';
|
export const API_URL = 'http://localhost:3001';
|
||||||
|
|
||||||
export const API_ENDPOINTS = {
|
export const API_ENDPOINTS = {
|
||||||
GET_EVENTS: 'GET_EVENTS',
|
GET_EVENTS: 'GET_EVENTS',
|
||||||
GET_ITEMS: 'GET_ITEMS',
|
GET_ITEMS: 'GET_ITEMS',
|
||||||
GET_STATUS: 'GET_STATUS',
|
GET_STATUS: 'GET_STATUS',
|
||||||
PLACE_BID: 'PLACE_BID',
|
PLACE_BID: 'PLACE_BID',
|
||||||
PURCHASE_ITEM: 'PURCHASE_ITEM',
|
PURCHASE_ITEM: 'PURCHASE_ITEM',
|
||||||
USER_SIGNUP: 'USER_SIGNUP',
|
USER_SIGNUP: 'USER_SIGNUP',
|
||||||
USER_PROFILE: 'USER_PROFILE',
|
USER_PROFILE: 'USER_PROFILE',
|
||||||
APPLE_SIGNUP: 'APPLE_SIGNUP',
|
APPLE_SIGNUP: 'APPLE_SIGNUP',
|
||||||
APPLE_LINK: 'APPLE_LINK',
|
APPLE_LINK: 'APPLE_LINK',
|
||||||
FACEBOOK_SIGNUP: 'FACEBOOK_SIGNUP',
|
FACEBOOK_SIGNUP: 'FACEBOOK_SIGNUP',
|
||||||
FACEBOOK_LINK: 'FACEBOOK_LINK',
|
FACEBOOK_LINK: 'FACEBOOK_LINK',
|
||||||
GOOGLE_SIGNUP: 'GOOGLE_SIGNUP',
|
GOOGLE_SIGNUP: 'GOOGLE_SIGNUP',
|
||||||
GOOGLE_LINK: 'GOOGLE_LINK',
|
GOOGLE_LINK: 'GOOGLE_LINK',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const PERMISSIONS = {
|
export const PERMISSIONS = {
|
||||||
FACEBOOK: [ 'email', 'public_profile' ],
|
FACEBOOK: ['email', 'public_profile'],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,25 +5,27 @@ import { placeBid } from '../../actions/auction.js';
|
|||||||
import AuctionListItem from '../../components/Auction/AuctionListItem.js';
|
import AuctionListItem from '../../components/Auction/AuctionListItem.js';
|
||||||
|
|
||||||
const mapStateToProps = (state, ownProps) => {
|
const mapStateToProps = (state, ownProps) => {
|
||||||
const { item } = ownProps;
|
const { item } = ownProps;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
description: item.get('description'),
|
description: item.get('description'),
|
||||||
donor: item.get('donor'),
|
donor: item.get('donor'),
|
||||||
end: item.get('end'),
|
end: item.get('end'),
|
||||||
id: item.get('id'),
|
id: item.get('id'),
|
||||||
images: item.get('images').toArray(),
|
images: item.get('images').toArray(),
|
||||||
start: item.get('start'),
|
start: item.get('start'),
|
||||||
startingPrice: item.get('startingPrice'),
|
startingPrice: item.get('startingPrice'),
|
||||||
subtitle: item.get('subtitle'),
|
subtitle: item.get('subtitle'),
|
||||||
title: item.get('title'),
|
title: item.get('title'),
|
||||||
type: item.get('type'),
|
type: item.get('type'),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
placeBid: (data) => dispatch(placeBid(data)),
|
placeBid: (data) => dispatch(placeBid(data)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps, null)(AuctionListItem);
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
null,
|
||||||
|
)(AuctionListItem);
|
||||||
|
|||||||
@@ -5,12 +5,15 @@ import { getItemBidCount, getItemPrice } from '../../selectors/auctions.js';
|
|||||||
import AuctionPriceAndBidCount from '../../components/Auction/AuctionPriceAndBidCount.js';
|
import AuctionPriceAndBidCount from '../../components/Auction/AuctionPriceAndBidCount.js';
|
||||||
|
|
||||||
function mapStateToProps(state, ownProps) {
|
function mapStateToProps(state, ownProps) {
|
||||||
const { itemId } = ownProps;
|
const { itemId } = ownProps;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
bidCount: getItemBidCount(state, itemId),
|
bidCount: getItemBidCount(state, itemId),
|
||||||
currentPrice: getItemPrice(state, itemId),
|
currentPrice: getItemPrice(state, itemId),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(mapStateToProps, null)(AuctionPriceAndBidCount);
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
null,
|
||||||
|
)(AuctionPriceAndBidCount);
|
||||||
|
|||||||
@@ -5,12 +5,15 @@ import { isBiddingItem, isWinningItem } from '../../selectors/auctions.js';
|
|||||||
import AuctionPriceAndBidCount from '../../components/Auction/BidStatus.js';
|
import AuctionPriceAndBidCount from '../../components/Auction/BidStatus.js';
|
||||||
|
|
||||||
function mapStateToProps(state, ownProps) {
|
function mapStateToProps(state, ownProps) {
|
||||||
const { itemId } = ownProps;
|
const { itemId } = ownProps;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isBidding: isBiddingItem(state, itemId),
|
isBidding: isBiddingItem(state, itemId),
|
||||||
isWinning: isWinningItem(state, itemId),
|
isWinning: isWinningItem(state, itemId),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(mapStateToProps, null)(AuctionPriceAndBidCount);
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
null,
|
||||||
|
)(AuctionPriceAndBidCount);
|
||||||
|
|||||||
@@ -6,14 +6,17 @@ import { getEventsAsList } from '../selectors/events.js';
|
|||||||
import Events from '../screens/Events.js';
|
import Events from '../screens/Events.js';
|
||||||
|
|
||||||
const matchStateToProps = (state) => {
|
const matchStateToProps = (state) => {
|
||||||
const events = getEventsAsList(state);
|
const events = getEventsAsList(state);
|
||||||
console.log('events:', events);
|
console.log('events:', events);
|
||||||
|
|
||||||
return { events };
|
return { events };
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
fetchEvents: () => dispatch(fetchEvents(dispatch)),
|
fetchEvents: () => dispatch(fetchEvents(dispatch)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(matchStateToProps, mapDispatchToProps)(Events);
|
export default connect(
|
||||||
|
matchStateToProps,
|
||||||
|
mapDispatchToProps,
|
||||||
|
)(Events);
|
||||||
|
|||||||
@@ -4,26 +4,28 @@ import { setActiveEvent } from '../../actions/events.js';
|
|||||||
import EventListItem from '../../components/Events/EventListItem.js';
|
import EventListItem from '../../components/Events/EventListItem.js';
|
||||||
|
|
||||||
const mapStateToProps = (state, ownProps) => {
|
const mapStateToProps = (state, ownProps) => {
|
||||||
const { event } = ownProps;
|
const { event } = ownProps;
|
||||||
|
|
||||||
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').toArray(),
|
images: event.get('images').toArray(),
|
||||||
isTicketed: event.get('isTicketed'),
|
isTicketed: event.get('isTicketed'),
|
||||||
postCount: event.get('posts').size,
|
postCount: event.get('posts').size,
|
||||||
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'),
|
||||||
title: event.get('title'),
|
title: event.get('title'),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
setActiveEvent: (eventId) => dispatch(setActiveEvent(eventId)),
|
setActiveEvent: (eventId) => dispatch(setActiveEvent(eventId)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps, null)(AuctionListItem);
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
null,
|
||||||
|
)(AuctionListItem);
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
import { Record } from 'immutable';
|
import { Record } from 'immutable';
|
||||||
|
|
||||||
export default class Auction extends Record({
|
export default class Auction extends Record({
|
||||||
id: null,
|
id: null,
|
||||||
bidCount: 0,
|
bidCount: 0,
|
||||||
isBidding: false,
|
isBidding: false,
|
||||||
isWinning: false,
|
isWinning: false,
|
||||||
itemPrice: 0,
|
itemPrice: 0,
|
||||||
}) {}
|
}) {}
|
||||||
|
|
||||||
Auction.fromJS = (data = {}) => {
|
Auction.fromJS = (data = {}) => {
|
||||||
return new Auction({
|
return new Auction({
|
||||||
id: data._id,
|
id: data._id,
|
||||||
...data,
|
...data,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,36 +4,36 @@ import Post from './Post.js';
|
|||||||
import TicketClass from './TicketClass.js';
|
import TicketClass from './TicketClass.js';
|
||||||
|
|
||||||
export default class Event extends Record({
|
export default class Event extends Record({
|
||||||
id: null,
|
id: null,
|
||||||
isTicketed: false,
|
isTicketed: false,
|
||||||
requireLoginToSeeAuction: false,
|
requireLoginToSeeAuction: false,
|
||||||
description: null,
|
description: null,
|
||||||
endTime: null,
|
endTime: null,
|
||||||
images: new List(),
|
images: new List(),
|
||||||
posts: new List(),
|
posts: new List(),
|
||||||
showFrom: null,
|
showFrom: null,
|
||||||
showUntil: null,
|
showUntil: null,
|
||||||
startTime: null,
|
startTime: null,
|
||||||
tagline: null,
|
tagline: null,
|
||||||
title: null,
|
title: null,
|
||||||
url: null,
|
url: null,
|
||||||
ticketClasses: new List(),
|
ticketClasses: new List(),
|
||||||
}) {
|
}) {
|
||||||
get isSoldOut() {
|
get isSoldOut() {
|
||||||
if (this.isTicketed) {
|
if (this.isTicketed) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.ticketClasses.find(t => t.available > 0) || false;
|
return this.ticketClasses.find((t) => t.available > 0) || false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Event.fromJS = (data = {}) => {
|
Event.fromJS = (data = {}) => {
|
||||||
return new Event({
|
return new Event({
|
||||||
id: data._id,
|
id: data._id,
|
||||||
...data,
|
...data,
|
||||||
images: new List(data.images),
|
images: new List(data.images),
|
||||||
posts: new List(data.posts.map(p => Post.fromJS(p))),
|
posts: new List(data.posts.map((p) => Post.fromJS(p))),
|
||||||
ticketClasses: new List(data.ticketClasses.map(t => TicketClass.fromJS(t))),
|
ticketClasses: new List(data.ticketClasses.map((t) => TicketClass.fromJS(t))),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,43 +1,43 @@
|
|||||||
import { List, Record } from 'immutable';
|
import { List, Record } from 'immutable';
|
||||||
|
|
||||||
export default class Item extends Record({
|
export default class Item extends Record({
|
||||||
bidCount: 0,
|
bidCount: 0,
|
||||||
bidIncrement: 10,
|
bidIncrement: 10,
|
||||||
catalogNumber: null,
|
catalogNumber: null,
|
||||||
currentPrice: 0,
|
currentPrice: 0,
|
||||||
description: null,
|
description: null,
|
||||||
donor: null,
|
donor: null,
|
||||||
end: null,
|
end: null,
|
||||||
estimatedValue: null,
|
estimatedValue: null,
|
||||||
eventId: null,
|
eventId: null,
|
||||||
hideAfterEnd: false,
|
hideAfterEnd: false,
|
||||||
hideBeforeStart: false,
|
hideBeforeStart: false,
|
||||||
id: null,
|
id: null,
|
||||||
images: new List(),
|
images: new List(),
|
||||||
isShippable: false,
|
isShippable: false,
|
||||||
notifyOnAvailable: false,
|
notifyOnAvailable: false,
|
||||||
quantityAvailable: 1,
|
quantityAvailable: 1,
|
||||||
soldCount: 0,
|
soldCount: 0,
|
||||||
start: null,
|
start: null,
|
||||||
startingPrice: null,
|
startingPrice: null,
|
||||||
subtitle: null,
|
subtitle: null,
|
||||||
title: null,
|
title: null,
|
||||||
type: null,
|
type: null,
|
||||||
shippingCost: 0,
|
shippingCost: 0,
|
||||||
}) {
|
}) {
|
||||||
get isSoldOut() {
|
get isSoldOut() {
|
||||||
return this.quantityAvailable > this.soldCount;
|
return this.quantityAvailable > this.soldCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
get totalWithShipping() {
|
get totalWithShipping() {
|
||||||
return this.currentPrice + this.shippingCost;
|
return this.currentPrice + this.shippingCost;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Item.fromJS = (data = {}) => {
|
Item.fromJS = (data = {}) => {
|
||||||
return new Item({
|
return new Item({
|
||||||
id: data._id,
|
id: data._id,
|
||||||
...data,
|
...data,
|
||||||
images: List(data.images),
|
images: List(data.images),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,20 +1,19 @@
|
|||||||
import { Record } from 'immutable';
|
import { Record } from 'immutable';
|
||||||
|
|
||||||
export default class Post extends Record({
|
export default class Post extends Record({
|
||||||
author: null,
|
author: null,
|
||||||
content: null,
|
content: null,
|
||||||
id: null,
|
id: null,
|
||||||
isPublic: false,
|
isPublic: false,
|
||||||
scheduledPost: false,
|
scheduledPost: false,
|
||||||
sendNotification: false,
|
sendNotification: false,
|
||||||
timestamp: null,
|
timestamp: null,
|
||||||
title: null,
|
title: null,
|
||||||
}) {};
|
}) {}
|
||||||
|
|
||||||
|
|
||||||
Post.fromJS = (data = {}) => {
|
Post.fromJS = (data = {}) => {
|
||||||
return new Post({
|
return new Post({
|
||||||
id: data._id,
|
id: data._id,
|
||||||
...data,
|
...data,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,44 +1,48 @@
|
|||||||
import { List, Record } from 'immutable';
|
import { List, Record } from 'immutable';
|
||||||
|
|
||||||
export default class Profile extends Record({
|
export default class Profile extends Record({
|
||||||
addresses: new List(),
|
addresses: new List(),
|
||||||
avatar: null,
|
avatar: null,
|
||||||
email: null,
|
email: null,
|
||||||
firstName: null,
|
firstName: null,
|
||||||
generatedNomDeBid: false,
|
generatedNomDeBid: false,
|
||||||
hasLinkedApple: false,
|
hasLinkedApple: false,
|
||||||
hasLinkedFacebook: false,
|
hasLinkedFacebook: false,
|
||||||
hasLinkedGoogle: false,
|
hasLinkedGoogle: false,
|
||||||
hasLocalAccount: false,
|
hasLocalAccount: false,
|
||||||
id: null,
|
id: null,
|
||||||
isAllowedToBid: false,
|
isAllowedToBid: false,
|
||||||
isOrganizationEmployee: false,
|
isOrganizationEmployee: false,
|
||||||
isVerified: false,
|
isVerified: false,
|
||||||
lastName: null,
|
lastName: null,
|
||||||
nomDeBid: null,
|
nomDeBid: null,
|
||||||
organizationIdentifier: null,
|
organizationIdentifier: null,
|
||||||
paymentToken: null,
|
paymentToken: null,
|
||||||
phones: new List(),
|
phones: new List(),
|
||||||
}) {
|
}) {
|
||||||
get canBid() {
|
get canBid() {
|
||||||
return this.isAllowedToBid && this.paymentToken !== null;
|
return this.isAllowedToBid && this.paymentToken !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
get fullName() {
|
get fullName() {
|
||||||
return `${this.firstName} ${this.lastName}`;
|
return `${this.firstName} ${this.lastName}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
get isRegisteredAccount() {
|
get isRegisteredAccount() {
|
||||||
return this.hasLinkedApple ||
|
return (
|
||||||
this.hasLinkedFacebook || this.hasLinkedGoogle || this.hasLocalAccount;
|
this.hasLinkedApple ||
|
||||||
}
|
this.hasLinkedFacebook ||
|
||||||
|
this.hasLinkedGoogle ||
|
||||||
|
this.hasLocalAccount
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Profile.fromJS = (data = {}) => {
|
Profile.fromJS = (data = {}) => {
|
||||||
return new Profile({
|
return new Profile({
|
||||||
id: data._id,
|
id: data._id,
|
||||||
...data,
|
...data,
|
||||||
addresses: new List(data.addresses),
|
addresses: new List(data.addresses),
|
||||||
phones: new List(data.phones),
|
phones: new List(data.phones),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,27 +1,27 @@
|
|||||||
import { List, Record } from 'immutable';
|
import { List, Record } from 'immutable';
|
||||||
|
|
||||||
export default class TicketClass extends Record({
|
export default class TicketClass extends Record({
|
||||||
available: 0,
|
available: 0,
|
||||||
capacity: 0,
|
capacity: 0,
|
||||||
endSale: null,
|
endSale: null,
|
||||||
id: null,
|
id: null,
|
||||||
itemId: null,
|
itemId: null,
|
||||||
name: null,
|
name: null,
|
||||||
price: 0,
|
price: 0,
|
||||||
startSale: null,
|
startSale: null,
|
||||||
}) {
|
}) {
|
||||||
get isAlmostGone() {
|
get isAlmostGone() {
|
||||||
return this.available < (this.capacity * 0.20);
|
return this.available < this.capacity * 0.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
get isSoldOut() {
|
get isSoldOut() {
|
||||||
return this.available === 0;
|
return this.available === 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TicketClass.fromJS = (data = {}) => {
|
TicketClass.fromJS = (data = {}) => {
|
||||||
return new TicketClass({
|
return new TicketClass({
|
||||||
id: data._id,
|
id: data._id,
|
||||||
...data,
|
...data,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,60 +5,60 @@ export const formatPrice = (price, format = '$ 0,0[.]00') => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getAuctionTime = ({ end, start }) => {
|
export const getAuctionTime = ({ end, start }) => {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const compareToEnd = new Date(end);
|
const compareToEnd = new Date(end);
|
||||||
const compareToStart = new Date(start);
|
const compareToStart = new Date(start);
|
||||||
|
|
||||||
let delta;
|
let delta;
|
||||||
if (now < start) {
|
if (now < start) {
|
||||||
delta = start - now;
|
delta = start - now;
|
||||||
return 'Bidding starts in ${parseTimeDifferential(delta)}';
|
return 'Bidding starts in ${parseTimeDifferential(delta)}';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (now > start && now < end) {
|
if (now > start && now < end) {
|
||||||
delta = end - now;
|
delta = end - now;
|
||||||
return 'Bidding ends in ${parseTimeDifferential(delta)}';
|
return 'Bidding ends in ${parseTimeDifferential(delta)}';
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'Bidding has ended';
|
return 'Bidding has ended';
|
||||||
};
|
};
|
||||||
|
|
||||||
export const parseHumanReadableTimeDifferential = (delta) => {
|
export const parseHumanReadableTimeDifferential = (delta) => {
|
||||||
const oneMinute = 60 * 1000;
|
const oneMinute = 60 * 1000;
|
||||||
const oneHour = oneMinute * 60;
|
const oneHour = oneMinute * 60;
|
||||||
const oneDay = oneHour * 24;
|
const oneDay = oneHour * 24;
|
||||||
const oneWeek = oneDay * 7;
|
const oneWeek = oneDay * 7;
|
||||||
const oneMonth = oneWeek * 4;
|
const oneMonth = oneWeek * 4;
|
||||||
|
|
||||||
let compare = delta / oneMonth;
|
let compare = delta / oneMonth;
|
||||||
if (compare >= 1) {
|
if (compare >= 1) {
|
||||||
compare = Math.floor(compare);
|
compare = Math.floor(compare);
|
||||||
return `${compare} month${compare > 1 ? 's' : ''}`;
|
return `${compare} month${compare > 1 ? 's' : ''}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
compare = delta / oneWeek;
|
compare = delta / oneWeek;
|
||||||
if (compare >= 1) {
|
if (compare >= 1) {
|
||||||
compare = Math.floor(compare);
|
compare = Math.floor(compare);
|
||||||
return `${compare} week${compare > 1 ? 's' : ''}`;
|
return `${compare} week${compare > 1 ? 's' : ''}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
compare = delta / oneDay;
|
compare = delta / oneDay;
|
||||||
if (compare > 1) {
|
if (compare > 1) {
|
||||||
compare = Math.floor(compare);
|
compare = Math.floor(compare);
|
||||||
return `${compare} day${compare > 1 ? 's' : ''}`;
|
return `${compare} day${compare > 1 ? 's' : ''}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
compare = delta / oneHour;
|
compare = delta / oneHour;
|
||||||
if (compare > 1) {
|
if (compare > 1) {
|
||||||
compare = Math.floor(compare);
|
compare = Math.floor(compare);
|
||||||
return `${compare} hour${compare > 1 ? 's' : ''}`;
|
return `${compare} hour${compare > 1 ? 's' : ''}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
compare = delta / oneMinute;
|
compare = delta / oneMinute;
|
||||||
if (compare > 1) {
|
if (compare > 1) {
|
||||||
compare = Math.floor(compare);
|
compare = Math.floor(compare);
|
||||||
return `${compare} minute${compare > 1 ? 's' : ''}`;
|
return `${compare} minute${compare > 1 ? 's' : ''}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'less than a minute';
|
return 'less than a minute';
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
import { SET_ACTIVE_EVENT, UNSET_ACTIVE_EVENT } from '../constants/actionTypes.js';
|
import { EVENTS_LOADED, SET_ACTIVE_EVENT, UNSET_ACTIVE_EVENT } from '../constants/actionTypes.js';
|
||||||
|
|
||||||
export const activeEvent = (state = null, action) => {
|
export const activeEvent = (state = null, action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case SET_ACTIVE_EVENT:
|
case EVENTS_LOADED:
|
||||||
return action.payload;
|
return action.payload.size === 1 ? action.payload.get(0).get('id') : null;
|
||||||
case UNSET_ACTIVE_EVENT:
|
case SET_ACTIVE_EVENT:
|
||||||
return null;
|
return action.payload;
|
||||||
default:
|
case UNSET_ACTIVE_EVENT:
|
||||||
return state;
|
return null;
|
||||||
}
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { SET_ACTIVE_ITEM, UNSET_ACTIVE_ITEM } from '../constants/actionTypes.js';
|
import { SET_ACTIVE_ITEM, UNSET_ACTIVE_ITEM } from '../constants/actionTypes.js';
|
||||||
|
|
||||||
export const activeItem = (state = null, action) => {
|
export const activeItem = (state = null, action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case SET_ACTIVE_ITEM:
|
case SET_ACTIVE_ITEM:
|
||||||
return action.payload;
|
return action.payload;
|
||||||
case UNSET_ACTIVE_ITEM:
|
case UNSET_ACTIVE_ITEM:
|
||||||
return null;
|
return null;
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ import { SET_AUCTION_FILTER } from '../constants/actionTypes.js';
|
|||||||
import { ITEM_FILTERS } from '../constants/constants.js';
|
import { ITEM_FILTERS } from '../constants/constants.js';
|
||||||
|
|
||||||
export const auctionFilter = (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;
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ import { SET_AUCTION_VIEW_MODE } from '../constants/actionTypes.js';
|
|||||||
import { AUCTION_VIEW_MODES } from '../constants/constants.js';
|
import { AUCTION_VIEW_MODES } from '../constants/constants.js';
|
||||||
|
|
||||||
export const auctionView = (state = AUCTION_VIEW_MODES.ALL, action) => {
|
export const auctionView = (state = AUCTION_VIEW_MODES.ALL, action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case SET_AUCTION_VIEW_MODE:
|
case SET_AUCTION_VIEW_MODE:
|
||||||
return action.payload;
|
return action.payload;
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,16 +3,16 @@ import { Map } from 'immutable';
|
|||||||
import { AUCTIONS_UPDATED, UPDATE_AUCTIONS } from '../constants/actionTypes.js';
|
import { AUCTIONS_UPDATED, UPDATE_AUCTIONS } from '../constants/actionTypes.js';
|
||||||
|
|
||||||
export const auctions = (state = new Map(), action) => {
|
export const auctions = (state = new Map(), action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case AUCTIONS_UPDATED:
|
case AUCTIONS_UPDATED:
|
||||||
return state.merge(
|
return state.merge(
|
||||||
action.payload.toMap().mapEntries((entry) => {
|
action.payload.toMap().mapEntries((entry) => {
|
||||||
const [, item] = entry;
|
const [, item] = entry;
|
||||||
return [`${item.id}`, item];
|
return [`${item.id}`, item];
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
case UPDATE_AUCTIONS:
|
case UPDATE_AUCTIONS:
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import { LOGIN_SUCCESS, SET_AUTH, UNSET_AUTH } from '../constants/actionTypes.js';
|
import { LOGIN_SUCCESS, SET_AUTH, UNSET_AUTH } from '../constants/actionTypes.js';
|
||||||
|
|
||||||
export const auth = (state = null, action) => {
|
export const auth = (state = null, action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case LOGIN_SUCCESS:
|
case LOGIN_SUCCESS:
|
||||||
return action.payload.token;
|
return action.payload.token;
|
||||||
case SET_AUTH:
|
case SET_AUTH:
|
||||||
return action.payload;
|
return action.payload;
|
||||||
case UNSET_AUTH:
|
case UNSET_AUTH:
|
||||||
return null;
|
return null;
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { BLOCK_UI, UNBLOCK_UI } from '../constants/actionTypes.js';
|
import { BLOCK_UI, UNBLOCK_UI } from '../constants/actionTypes.js';
|
||||||
|
|
||||||
export const blockUI = (state = false, action) => {
|
export const blockUI = (state = false, action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case BLOCK_UI:
|
case BLOCK_UI:
|
||||||
return true;
|
return true;
|
||||||
case UNBLOCK_UI:
|
case UNBLOCK_UI:
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,15 +3,15 @@ import { Map } from 'immutable';
|
|||||||
import { EVENTS_LOADED, GET_EVENTS } from '../constants/actionTypes.js';
|
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:
|
||||||
const mapped = action.payload.toMap().mapEntries((entry) => {
|
const mapped = action.payload.toMap().mapEntries((entry) => {
|
||||||
const [, event] = entry;
|
const [, event] = entry;
|
||||||
return [`${event.id}`, event];
|
return [`${event.id}`, event];
|
||||||
});
|
});
|
||||||
return state.merge(mapped);
|
return state.merge(mapped);
|
||||||
case GET_EVENTS:
|
case GET_EVENTS:
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,16 +12,16 @@ import { items } from './items.js';
|
|||||||
import { profile } from './profile.js';
|
import { profile } from './profile.js';
|
||||||
|
|
||||||
const rootReducer = combineReducers({
|
const rootReducer = combineReducers({
|
||||||
activeEvent,
|
activeEvent,
|
||||||
activeItem,
|
activeItem,
|
||||||
auctionFilter,
|
auctionFilter,
|
||||||
auctions,
|
auctions,
|
||||||
auctionView,
|
auctionView,
|
||||||
auth,
|
auth,
|
||||||
blockUI,
|
blockUI,
|
||||||
events,
|
events,
|
||||||
items,
|
items,
|
||||||
profile,
|
profile,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default rootReducer;
|
export default rootReducer;
|
||||||
|
|||||||
@@ -1,20 +1,17 @@
|
|||||||
import { Map } from 'immutable';
|
import { Map } from 'immutable';
|
||||||
|
|
||||||
import {
|
import { GET_ITEMS, ITEMS_LOADED } from '../constants/actionTypes.js';
|
||||||
GET_ITEMS,
|
|
||||||
ITEMS_LOADED,
|
|
||||||
} from '../constants/actionTypes.js';
|
|
||||||
|
|
||||||
export const items = (state = new Map(), action) => {
|
export const items = (state = new Map(), action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case ITEMS_LOADED:
|
case ITEMS_LOADED:
|
||||||
const mapped = action.payload.toMap().mapEntries((entry) => {
|
const mapped = action.payload.toMap().mapEntries((entry) => {
|
||||||
const [, item] = entry;
|
const [, item] = entry;
|
||||||
return [`${item.id}`, item];
|
return [`${item.id}`, item];
|
||||||
});
|
});
|
||||||
return state.merge(mapped);
|
return state.merge(mapped);
|
||||||
case GET_ITEMS:
|
case GET_ITEMS:
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
import { Map } from 'immutable';
|
import { Map } from 'immutable';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
LOGIN_SUCCESS,
|
LOGIN_SUCCESS,
|
||||||
SET_PROFILE,
|
SET_PROFILE,
|
||||||
UNSET_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:
|
case LOGIN_SUCCESS:
|
||||||
return action.payload.user;
|
return action.payload.user;
|
||||||
case SET_PROFILE:
|
case SET_PROFILE:
|
||||||
return action.payload;
|
return action.payload;
|
||||||
case UNSET_PROFILE:
|
case UNSET_PROFILE:
|
||||||
return new Map();
|
return new Map();
|
||||||
case UPDATE_PROFILE:
|
case UPDATE_PROFILE:
|
||||||
return action.payload;
|
return action.payload;
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
298
app/router.js
298
app/router.js
@@ -16,155 +16,177 @@ import Profile from './screens/Profile.container.js';
|
|||||||
import Register from './screens/Register.js';
|
import Register from './screens/Register.js';
|
||||||
import SignInOrRegister from './screens/SignInOrRegister.js';
|
import SignInOrRegister from './screens/SignInOrRegister.js';
|
||||||
|
|
||||||
export const Tabs = createBottomTabNavigator({
|
|
||||||
'Event': {
|
|
||||||
screen: Event,
|
|
||||||
navigationOptions: {
|
|
||||||
tabBarLabel: 'Event',
|
|
||||||
tabBarIcon: ({ tintColor }) => <Icon name="black-tie" type="font-awesome" size={28} color={tintColor} />,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'Auction': {
|
|
||||||
screen: Auction,
|
|
||||||
navigationOptions: {
|
|
||||||
tabBarLabel: 'Silent Auction',
|
|
||||||
tabBarIcon: ({ tintColor }) => <Icon name="gavel" type="font-awesome" size={28} color={tintColor} />,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'Bazaar': {
|
|
||||||
screen: Marketplace,
|
|
||||||
navigationOptions: {
|
|
||||||
tabBarLabel: 'Bazaar',
|
|
||||||
tabBarIcon: ({ tintColor }) => <Icon name="store" type="fontisto" size={28} color={tintColor} />,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'Profile': {
|
|
||||||
screen: Profile,
|
|
||||||
navigationOptions: {
|
|
||||||
tabBarLabel: 'Profile',
|
|
||||||
tabBarIcon: ({ tintColor }) => <Icon name="ios-person" type="font-awesome" size={28} color={tintColor} />,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
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,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
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,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const EventsStack = createStackNavigator({
|
export const EventsStack = createStackNavigator({
|
||||||
Events: {
|
Events: {
|
||||||
screen: Events,
|
screen: Events,
|
||||||
navigationOptions: ({ navigation }) => ({
|
navigationOptions: ({ navigation }) => ({
|
||||||
header: <AppHeader navigation={navigation} />,
|
header: <AppHeader navigation={navigation} />,
|
||||||
tabBarVisible: false,
|
tabBarVisible: false,
|
||||||
gesturesEnabled: false,
|
gesturesEnabled: false,
|
||||||
}),
|
}),
|
||||||
}
|
},
|
||||||
|
Event: {
|
||||||
|
screen: Event,
|
||||||
|
navigationOptions: ({ navigation }) => ({
|
||||||
|
header: <AppHeader navigation={navigation} />,
|
||||||
|
tabBarVisible: false,
|
||||||
|
gesturesEnabled: false,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const Tabs = createBottomTabNavigator({
|
||||||
|
Event: {
|
||||||
|
screen: EventsStack,
|
||||||
|
navigationOptions: {
|
||||||
|
tabBarLabel: 'Event',
|
||||||
|
tabBarIcon: ({ tintColor }) => (
|
||||||
|
<Icon name="black-tie" type="font-awesome" size={28} color={tintColor} />
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Auction: {
|
||||||
|
screen: AuctionStack,
|
||||||
|
navigationOptions: {
|
||||||
|
tabBarLabel: 'Silent Auction',
|
||||||
|
tabBarIcon: ({ tintColor }) => (
|
||||||
|
<Icon name="gavel" type="font-awesome" size={28} color={tintColor} />
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Bazaar: {
|
||||||
|
screen: BazaarStack,
|
||||||
|
navigationOptions: {
|
||||||
|
tabBarLabel: 'Bazaar',
|
||||||
|
tabBarIcon: ({ tintColor }) => (
|
||||||
|
<Icon name="store" type="fontisto" size={28} color={tintColor} />
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Profile: {
|
||||||
|
screen: Profile,
|
||||||
|
navigationOptions: {
|
||||||
|
tabBarLabel: 'Profile',
|
||||||
|
tabBarIcon: ({ tintColor }) => (
|
||||||
|
<Icon name="ios-person" type="font-awesome" size={28} color={tintColor} />
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const createRootNavigator = () => {
|
export const createRootNavigator = () => {
|
||||||
return StackNavigator(
|
return StackNavigator(
|
||||||
{
|
{
|
||||||
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: {
|
SignInOrRegisterStack: {
|
||||||
screen: Tabs,
|
screen: SignInOrRegister,
|
||||||
navigationOptions: {
|
navigationOptions: {
|
||||||
gesturesEnabled: false,
|
gesturesEnabled: false,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
Tabs: {
|
||||||
{
|
screen: Tabs,
|
||||||
mode: "modal",
|
navigationOptions: {
|
||||||
}
|
gesturesEnabled: false,
|
||||||
);
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
mode: 'modal',
|
||||||
|
},
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,16 +8,19 @@ import { getAuctionItemsAsList } from '../selectors/items.js';
|
|||||||
import Auction from './Auction.js';
|
import Auction from './Auction.js';
|
||||||
|
|
||||||
const matchStateToProps = (state) => {
|
const matchStateToProps = (state) => {
|
||||||
const items = getAuctionItemsAsList(state);
|
const items = getAuctionItemsAsList(state);
|
||||||
console.log('items:', items);
|
console.log('items:', items);
|
||||||
|
|
||||||
return { items };
|
return { items };
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
changeViewMode: (mode) => dispatch(changeViewMode(mode)),
|
changeViewMode: (mode) => dispatch(changeViewMode(mode)),
|
||||||
fetchItems: () => dispatch(fetchItems(dispatch)),
|
fetchItems: () => dispatch(fetchItems(dispatch)),
|
||||||
fetchStatus: () => dispatch(fetchAuctionStatus(dispatch)),
|
fetchStatus: () => dispatch(fetchAuctionStatus(dispatch)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(matchStateToProps, mapDispatchToProps)(Auction);
|
export default connect(
|
||||||
|
matchStateToProps,
|
||||||
|
mapDispatchToProps,
|
||||||
|
)(Auction);
|
||||||
|
|||||||
@@ -2,11 +2,7 @@ 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, Text, View } from 'react-native';
|
||||||
FlatList,
|
|
||||||
Text,
|
|
||||||
View,
|
|
||||||
} from 'react-native';
|
|
||||||
|
|
||||||
import { SORT_MODES, AUCTION_VIEW_MODES } from '../constants/constants.js';
|
import { SORT_MODES, AUCTION_VIEW_MODES } from '../constants/constants.js';
|
||||||
|
|
||||||
@@ -16,70 +12,74 @@ import AuctionListItem from '../containers/Auction/AuctionListItem.js';
|
|||||||
import styles from './Auction.styles.js';
|
import styles from './Auction.styles.js';
|
||||||
|
|
||||||
export default class Auction extends Component {
|
export default class Auction extends Component {
|
||||||
static get propTypes() {
|
static get propTypes() {
|
||||||
return {
|
return {
|
||||||
changeFilter: PropTypes.func,
|
changeFilter: PropTypes.func,
|
||||||
changeViewMode: PropTypes.func.isRequired,
|
changeViewMode: PropTypes.func.isRequired,
|
||||||
fetchItems: PropTypes.func.isRequired,
|
fetchItems: PropTypes.func.isRequired,
|
||||||
fetchStatus: PropTypes.func.isRequired,
|
fetchStatus: PropTypes.func.isRequired,
|
||||||
items: PropTypes.oneOfType([
|
items: PropTypes.oneOfType([PropTypes.array, PropTypes.instanceOf(List)]),
|
||||||
PropTypes.array,
|
};
|
||||||
PropTypes.instanceOf(List),
|
}
|
||||||
]),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static get defaultProps() {
|
static get defaultProps() {
|
||||||
return {
|
return {
|
||||||
changeFilter: () => { console.log('Change Filter Default Prop', arguments); },
|
changeFilter: () => {
|
||||||
items: [],
|
console.log('Change Filter Default Prop', arguments);
|
||||||
};
|
},
|
||||||
}
|
items: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.changeFilter = this.changeFilter.bind(this);
|
this.changeFilter = this.changeFilter.bind(this);
|
||||||
this.changeViewMode = this.changeViewMode.bind(this);
|
this.changeViewMode = this.changeViewMode.bind(this);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
sort: SORT_MODES.TITLE_ASC,
|
sort: SORT_MODES.TITLE_ASC,
|
||||||
view: AUCTION_VIEW_MODES.ALL,
|
view: AUCTION_VIEW_MODES.ALL,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.fetchStatus();
|
this.props.fetchStatus();
|
||||||
this.props.fetchItems();
|
this.props.fetchItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
changeFilter(filter) {
|
changeFilter(filter) {
|
||||||
this.props.changeFilter('auction', filter);
|
this.props.changeFilter('auction', filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
_keyExtractor = (item, index) => `${item._id}_${index}`;
|
changeViewMode(viewMode) {
|
||||||
|
this.props.changeViewMode(viewMode);
|
||||||
|
}
|
||||||
|
|
||||||
_renderAuctionListItem = ({ item }) => <AuctionListItem item={item} />;
|
_keyExtractor = (item, index) => `${item.id}_${index}`;
|
||||||
|
|
||||||
render() {
|
_renderAuctionListItem = ({ item }) => <AuctionListItem item={item} />;
|
||||||
const { items } = this.props;
|
|
||||||
const { sort, view } = this.state;
|
|
||||||
|
|
||||||
return (
|
render() {
|
||||||
<View style={styles.container}>
|
const { items } = this.props;
|
||||||
<FilterBar
|
const { sort, view } = this.state;
|
||||||
changeFilterer={this.changeFilter}
|
|
||||||
/>
|
return (
|
||||||
{items.size > 0 && (
|
<View style={styles.container}>
|
||||||
<FlatList
|
<FilterBar
|
||||||
data={items}
|
changeFilterer={this.changeFilter}
|
||||||
keyExtractor={this._keyExtractor}
|
changeViewMode={this.changeViewMode}
|
||||||
renderItem={this._renderAuctionListItem}
|
/>
|
||||||
contentContainerStyle={styles.itemListContentContainer}
|
{items.size > 0 && (
|
||||||
style={styles.itemList}
|
<FlatList
|
||||||
/>
|
data={items}
|
||||||
)}
|
keyExtractor={this._keyExtractor}
|
||||||
</View>
|
renderItem={this._renderAuctionListItem}
|
||||||
);
|
contentContainerStyle={styles.itemListContentContainer}
|
||||||
}
|
style={styles.itemList}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
import { StyleSheet } from 'react-native';
|
import { StyleSheet } from 'react-native';
|
||||||
|
|
||||||
export const styles = StyleSheet.create({
|
export default (styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
backgroundColor: '#F5FCFF',
|
backgroundColor: '#F5FCFF',
|
||||||
},
|
},
|
||||||
itemList: {
|
itemList: {
|
||||||
width: '100%',
|
width: '100%',
|
||||||
},
|
},
|
||||||
itemListContentContainer: {
|
itemListContentContainer: {
|
||||||
alignItems: 'stretch',
|
alignItems: 'stretch',
|
||||||
justifyContent: 'flex-start',
|
justifyContent: 'flex-start',
|
||||||
},
|
},
|
||||||
});
|
}));
|
||||||
|
|||||||
@@ -1,32 +1,26 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import {
|
import { StyleSheet, Text, View } from 'react-native';
|
||||||
StyleSheet,
|
|
||||||
Text,
|
|
||||||
View,
|
|
||||||
} from 'react-native';
|
|
||||||
|
|
||||||
export default class Checkout extends Component {
|
export default class Checkout extends Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<Text style={styles.title}>
|
<Text style={styles.title}>Checkout</Text>
|
||||||
Checkout
|
</View>
|
||||||
</Text>
|
);
|
||||||
</View>
|
}
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
backgroundColor: '#F5FCFF',
|
backgroundColor: '#F5FCFF',
|
||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
margin: 10,
|
margin: 10,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,30 +7,33 @@ import { getActiveEvent, getDefaultEvent } from '../selectors/events.js';
|
|||||||
import Event from './Event.js';
|
import Event from './Event.js';
|
||||||
|
|
||||||
const matchStateToProps = (state) => {
|
const matchStateToProps = (state) => {
|
||||||
const event = getActiveEvent(state) || getDefaultEvent(state) || new EventRecord();
|
const event = getActiveEvent(state) || getDefaultEvent(state) || new EventRecord();
|
||||||
|
|
||||||
if (!event) {
|
if (!event) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
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').toArray(),
|
images: event.get('images').toArray(),
|
||||||
isTicketed: event.get('isTicketed'),
|
isTicketed: event.get('isTicketed'),
|
||||||
posts: event.get('posts').toArray(),
|
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').toArray(),
|
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) => ({});
|
||||||
|
|
||||||
export default connect(matchStateToProps, mapDispatchToProps)(Event);
|
export default connect(
|
||||||
|
matchStateToProps,
|
||||||
|
mapDispatchToProps,
|
||||||
|
)(Event);
|
||||||
|
|||||||
@@ -5,82 +5,76 @@ import { Text, View } from 'react-native';
|
|||||||
import styles from './Event.styles.js';
|
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,
|
description: PropTypes.string,
|
||||||
endTime: PropTypes.string,
|
endTime: PropTypes.string,
|
||||||
id: PropTypes.string,
|
id: PropTypes.string,
|
||||||
images: PropTypes.arrayOf(
|
images: PropTypes.arrayOf(
|
||||||
PropTypes.shape({
|
PropTypes.shape({
|
||||||
url: PropTypes.string,
|
url: PropTypes.string,
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
isTicketed: PropTypes.bool,
|
isTicketed: PropTypes.bool,
|
||||||
posts: PropTypes.arrayOf(
|
posts: PropTypes.arrayOf(
|
||||||
PropTypes.shape({
|
PropTypes.shape({
|
||||||
author: PropTypes.string,
|
author: PropTypes.string,
|
||||||
content: PropTypes.string,
|
content: PropTypes.string,
|
||||||
id: PropTypes.string,
|
id: PropTypes.string,
|
||||||
isPublic: PropTypes.bool,
|
isPublic: PropTypes.bool,
|
||||||
scheduledPost: PropTypes.bool,
|
scheduledPost: PropTypes.bool,
|
||||||
sendNotification: PropTypes.bool,
|
sendNotification: PropTypes.bool,
|
||||||
timestamp: PropTypes.string,
|
timestamp: PropTypes.string,
|
||||||
title: PropTypes.string,
|
title: PropTypes.string,
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
requireLoginToSeeAuction: PropTypes.bool,
|
requireLoginToSeeAuction: PropTypes.bool,
|
||||||
showFrom: PropTypes.string,
|
showFrom: PropTypes.string,
|
||||||
showUntil: PropTypes.string,
|
showUntil: PropTypes.string,
|
||||||
startTime: PropTypes.string,
|
startTime: PropTypes.string,
|
||||||
tagline: PropTypes.string,
|
tagline: PropTypes.string,
|
||||||
ticketClasses: PropTypes.arrayOf(
|
ticketClasses: PropTypes.arrayOf(PropTypes.shape({})),
|
||||||
PropTypes.shape({
|
title: PropTypes.string,
|
||||||
|
url: PropTypes.string,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
}),
|
static get defaultProps() {
|
||||||
),
|
return {
|
||||||
title: PropTypes.string,
|
images: null,
|
||||||
url: PropTypes.string,
|
isTicketed: false,
|
||||||
};
|
posts: null,
|
||||||
}
|
requireLoginToSeeAuction: false,
|
||||||
|
tagline: null,
|
||||||
|
ticketClasses: null,
|
||||||
|
url: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
static get defaultProps() {
|
constructor(props) {
|
||||||
return {
|
super(props);
|
||||||
images: null,
|
}
|
||||||
isTicketed: false,
|
|
||||||
posts: null,
|
|
||||||
requireLoginToSeeAuction: false,
|
|
||||||
tagline: null,
|
|
||||||
ticketClasses: null,
|
|
||||||
url: null,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(props) {
|
render() {
|
||||||
super(props);
|
const {
|
||||||
}
|
description,
|
||||||
|
endTime,
|
||||||
|
images,
|
||||||
|
isTicketed,
|
||||||
|
requireLoginToSeeAuction,
|
||||||
|
showFrom,
|
||||||
|
showUntil,
|
||||||
|
startTime,
|
||||||
|
tagline,
|
||||||
|
ticketClasses,
|
||||||
|
title,
|
||||||
|
url,
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
render() {
|
return (
|
||||||
const {
|
<View style={styles.container}>
|
||||||
description,
|
<Text style={styles.title}>Event</Text>
|
||||||
endTime,
|
</View>
|
||||||
images,
|
);
|
||||||
isTicketed,
|
}
|
||||||
requireLoginToSeeAuction,
|
|
||||||
showFrom,
|
|
||||||
showUntil,
|
|
||||||
startTime,
|
|
||||||
tagline,
|
|
||||||
ticketClasses,
|
|
||||||
title,
|
|
||||||
url,
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<View style={styles.container}>
|
|
||||||
<Text style={styles.title}>
|
|
||||||
Event
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,15 @@
|
|||||||
import { StyleSheet } from 'react-native';
|
import { StyleSheet } from 'react-native';
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
export default (styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
backgroundColor: '#F5FCFF',
|
backgroundColor: '#F5FCFF',
|
||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
margin: 10,
|
margin: 10,
|
||||||
}
|
},
|
||||||
});
|
}));
|
||||||
|
|
||||||
export default styles;
|
|
||||||
|
|||||||
@@ -1,19 +1,22 @@
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
import { setActiveEvent } from '../actions/activeEvent.js';
|
||||||
import { fetchEvents } from '../actions/events.js';
|
import { fetchEvents } from '../actions/events.js';
|
||||||
import { getEventsAsList } from '../selectors/events.js';
|
import { getEventsAsList } from '../selectors/events.js';
|
||||||
|
|
||||||
import Events from './Events.js';
|
import Events from './Events.js';
|
||||||
|
|
||||||
const matchStateToProps = (state) => {
|
const matchStateToProps = (state) => {
|
||||||
const events = getEventsAsList(state);
|
const events = getEventsAsList(state);
|
||||||
console.log('events:', events);
|
return { events };
|
||||||
|
|
||||||
return { events };
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
fetchEvents: () => dispatch(fetchEvents(dispatch)),
|
fetchEvents: () => dispatch(fetchEvents()),
|
||||||
|
setActiveEvent: (eventId) => dispatch(setActiveEvent(eventId)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(matchStateToProps, mapDispatchToProps)(Events);
|
export default connect(
|
||||||
|
matchStateToProps,
|
||||||
|
mapDispatchToProps,
|
||||||
|
)(Events);
|
||||||
|
|||||||
@@ -1,58 +1,71 @@
|
|||||||
|
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, StyleSheet, Text, View } from 'react-native';
|
||||||
StyleSheet,
|
|
||||||
Text,
|
import EventListItem from '../components/Events/EventListItem.js';
|
||||||
View,
|
|
||||||
} from 'react-native';
|
|
||||||
|
|
||||||
export default class Events extends Component {
|
export default class Events extends Component {
|
||||||
static get propTypes() {
|
static get propTypes() {
|
||||||
return {
|
return {
|
||||||
events: PropTypes.array.isRequired,
|
events: PropTypes.instanceOf(List),
|
||||||
fetchEvents: PropTypes.func.isRequired,
|
fetchEvents: PropTypes.func.isRequired,
|
||||||
};
|
setActiveEvent: PropTypes.func.isRequired,
|
||||||
}
|
};
|
||||||
|
}
|
||||||
|
|
||||||
constructor(props) {
|
static get defaultProps() {
|
||||||
super(props);
|
return {
|
||||||
}
|
events: new List(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
constructor(props) {
|
||||||
this.props.fetchEvents();
|
super(props);
|
||||||
}
|
|
||||||
|
|
||||||
_keyExtractor = (event, index) => `${event._id}_${index}`;
|
this._setActiveEvent = this.setActiveEvent.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
_renderEventListItem = ({ event }) => <EventListItem event={event} />;
|
componentDidMount() {
|
||||||
|
this.props.fetchEvents();
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
setActiveEvent(eventId) {
|
||||||
const { events } = this.props;
|
this.props.setActiveEvent(eventId);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
_keyExtractor = (event, index) => `${event.id}_${index}`;
|
||||||
<View style={styles.container}>
|
|
||||||
{events.size > 0 && (
|
_renderEventListItem = ({ event }) => (
|
||||||
<FlatList
|
<EventListItem {...event} setActiveEvent={this.setActiveEvent} />
|
||||||
data={events}
|
|
||||||
keyExtractor={this._keyExtractor}
|
|
||||||
renderItem={this._renderEventListItem}
|
|
||||||
contentContainerStyle={styles.eventListContentContainer}
|
|
||||||
style={styles.eventList}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</View>
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
render() {
|
||||||
|
const { events } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
{events.size > 0 && (
|
||||||
|
<FlatList
|
||||||
|
data={events}
|
||||||
|
keyExtractor={this._keyExtractor}
|
||||||
|
renderItem={this._renderEventListItem}
|
||||||
|
contentContainerStyle={styles.eventListContentContainer}
|
||||||
|
style={styles.eventList}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
backgroundColor: '#F5FCFF',
|
backgroundColor: '#F5FCFF',
|
||||||
},
|
},
|
||||||
eventListContentContainer: {
|
eventListContentContainer: {},
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,32 +1,26 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import {
|
import { StyleSheet, Text, View } from 'react-native';
|
||||||
StyleSheet,
|
|
||||||
Text,
|
|
||||||
View,
|
|
||||||
} from 'react-native';
|
|
||||||
|
|
||||||
export default class ImageDetail extends Component {
|
export default class ImageDetail extends Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<Text style={styles.title}>
|
<Text style={styles.title}>Item</Text>
|
||||||
Item
|
</View>
|
||||||
</Text>
|
);
|
||||||
</View>
|
}
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
backgroundColor: '#F5FCFF',
|
backgroundColor: '#F5FCFF',
|
||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
margin: 10,
|
margin: 10,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,32 +1,26 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import {
|
import { StyleSheet, Text, View } from 'react-native';
|
||||||
StyleSheet,
|
|
||||||
Text,
|
|
||||||
View,
|
|
||||||
} from 'react-native';
|
|
||||||
|
|
||||||
export default class Item extends Component {
|
export default class Item extends Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<Text style={styles.title}>
|
<Text style={styles.title}>Item</Text>
|
||||||
Item
|
</View>
|
||||||
</Text>
|
);
|
||||||
</View>
|
}
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
backgroundColor: '#F5FCFF',
|
backgroundColor: '#F5FCFF',
|
||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
margin: 10,
|
margin: 10,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,32 +1,26 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import {
|
import { StyleSheet, Text, View } from 'react-native';
|
||||||
StyleSheet,
|
|
||||||
Text,
|
|
||||||
View,
|
|
||||||
} from 'react-native';
|
|
||||||
|
|
||||||
export default class Login extends Component {
|
export default class Login extends Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<Text style={styles.title}>
|
<Text style={styles.title}>Login</Text>
|
||||||
Login
|
</View>
|
||||||
</Text>
|
);
|
||||||
</View>
|
}
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
backgroundColor: '#F5FCFF',
|
backgroundColor: '#F5FCFF',
|
||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
margin: 10,
|
margin: 10,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,11 +2,7 @@ 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, Text, View } from 'react-native';
|
||||||
FlatList,
|
|
||||||
Text,
|
|
||||||
View,
|
|
||||||
} from 'react-native';
|
|
||||||
|
|
||||||
import { SORT_MODES, AUCTION_VIEW_MODES } from '../constants/constants.js';
|
import { SORT_MODES, AUCTION_VIEW_MODES } from '../constants/constants.js';
|
||||||
|
|
||||||
@@ -16,70 +12,67 @@ import AuctionListItem from '../containers/Auction/AuctionListItem.js';
|
|||||||
//import styles from './Marketplace.styles.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,
|
||||||
changeViewMode: PropTypes.func.isRequired,
|
changeViewMode: PropTypes.func.isRequired,
|
||||||
fetchItems: PropTypes.func.isRequired,
|
fetchItems: PropTypes.func.isRequired,
|
||||||
fetchStatus: PropTypes.func.isRequired,
|
fetchStatus: PropTypes.func.isRequired,
|
||||||
items: PropTypes.oneOfType([
|
items: PropTypes.oneOfType([PropTypes.array, PropTypes.instanceOf(List)]),
|
||||||
PropTypes.array,
|
};
|
||||||
PropTypes.instanceOf(List),
|
}
|
||||||
]),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static get defaultProps() {
|
static get defaultProps() {
|
||||||
return {
|
return {
|
||||||
changeFilter: () => { console.log('Change Filter Default Prop', arguments); },
|
changeFilter: () => {
|
||||||
items: [],
|
console.log('Change Filter Default Prop', arguments);
|
||||||
};
|
},
|
||||||
}
|
items: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.changeFilter = this.changeFilter.bind(this);
|
this.changeFilter = this.changeFilter.bind(this);
|
||||||
this.changeViewMode = this.changeViewMode.bind(this);
|
this.changeViewMode = this.changeViewMode.bind(this);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
sort: SORT_MODES.TITLE_ASC,
|
sort: SORT_MODES.TITLE_ASC,
|
||||||
view: AUCTION_VIEW_MODES.ALL,
|
view: AUCTION_VIEW_MODES.ALL,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.fetchStatus();
|
this.props.fetchStatus();
|
||||||
this.props.fetchItems();
|
this.props.fetchItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
changeFilter(filter) {
|
changeFilter(filter) {
|
||||||
this.props.changeFilter('auction', filter);
|
this.props.changeFilter('auction', filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
_keyExtractor = (item, index) => `${item._id}_${index}`;
|
_keyExtractor = (item, index) => `${item._id}_${index}`;
|
||||||
|
|
||||||
_renderAuctionListItem = ({ item }) => <AuctionListItem item={item} />;
|
_renderAuctionListItem = ({ item }) => <AuctionListItem item={item} />;
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { items } = this.props;
|
const { items } = this.props;
|
||||||
const { sort, view } = this.state;
|
const { sort, view } = this.state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<FilterBar
|
<FilterBar changeFilterer={this.changeFilter} />
|
||||||
changeFilterer={this.changeFilter}
|
{items.size > 0 && (
|
||||||
/>
|
<FlatList
|
||||||
{items.size > 0 && (
|
data={items}
|
||||||
<FlatList
|
keyExtractor={this._keyExtractor}
|
||||||
data={items}
|
renderItem={this._renderAuctionListItem}
|
||||||
keyExtractor={this._keyExtractor}
|
contentContainerStyle={styles.itemListContentContainer}
|
||||||
renderItem={this._renderAuctionListItem}
|
style={styles.itemList}
|
||||||
contentContainerStyle={styles.itemListContentContainer}
|
/>
|
||||||
style={styles.itemList}
|
)}
|
||||||
/>
|
</View>
|
||||||
)}
|
);
|
||||||
</View>
|
}
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,27 +6,30 @@ import { getNomDeBid, getProfile, isAllowedToBid } from '../selectors/profile.js
|
|||||||
import Profile from './Profile.js';
|
import Profile from './Profile.js';
|
||||||
|
|
||||||
const matchStateToProps = (state) => {
|
const matchStateToProps = (state) => {
|
||||||
const profile = getProfile(state);
|
const profile = getProfile(state);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
hasLinkedApple: profile.get('hasLinkedApple'),
|
hasLinkedApple: profile.get('hasLinkedApple'),
|
||||||
hasLinkedFacebook: profile.get('hasLinkedFacebook'),
|
hasLinkedFacebook: profile.get('hasLinkedFacebook'),
|
||||||
hasLinkedGoogle: profile.get('hasLinkedGoogle'),
|
hasLinkedGoogle: profile.get('hasLinkedGoogle'),
|
||||||
hasLocalAccount: profile.get('hasLocalAccount'),
|
hasLocalAccount: profile.get('hasLocalAccount'),
|
||||||
hasRegisteredAcccount: profile.get('hasRegisteredAcccount'),
|
hasRegisteredAcccount: profile.get('hasRegisteredAcccount'),
|
||||||
id: profile.get('id'),
|
id: profile.get('id'),
|
||||||
isAllowedToBid: isAllowedToBid(state),
|
isAllowedToBid: isAllowedToBid(state),
|
||||||
isVerified: profile.get('isVerified'),
|
isVerified: profile.get('isVerified'),
|
||||||
lastName: profile.get('lastName'),
|
lastName: profile.get('lastName'),
|
||||||
nomDeBid: getNomDeBid(state),
|
nomDeBid: getNomDeBid(state),
|
||||||
organizationIdentifier: profile.get('organizationIdentifier'),
|
organizationIdentifier: profile.get('organizationIdentifier'),
|
||||||
paymentToken: profile.get('paymentToken'),
|
paymentToken: profile.get('paymentToken'),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
fetchProfile: () => dispatch(fetchProfile(dispatch)),
|
fetchProfile: () => dispatch(fetchProfile(dispatch)),
|
||||||
updateProfile: () => dispatch(updateProfile(dispatch)),
|
updateProfile: () => dispatch(updateProfile(dispatch)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(matchStateToProps, mapDispatchToProps)(Profile);
|
export default connect(
|
||||||
|
matchStateToProps,
|
||||||
|
mapDispatchToProps,
|
||||||
|
)(Profile);
|
||||||
|
|||||||
@@ -1,32 +1,26 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import {
|
import { StyleSheet, Text, View } from 'react-native';
|
||||||
StyleSheet,
|
|
||||||
Text,
|
|
||||||
View,
|
|
||||||
} from 'react-native';
|
|
||||||
|
|
||||||
export default class Profile extends Component {
|
export default class Profile extends Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<Text style={styles.title}>
|
<Text style={styles.title}>Profile</Text>
|
||||||
Profile
|
</View>
|
||||||
</Text>
|
);
|
||||||
</View>
|
}
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
backgroundColor: '#F5FCFF',
|
backgroundColor: '#F5FCFF',
|
||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
margin: 10,
|
margin: 10,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import {
|
import { checkEmailAvailability, checkNomAvailability, registerUser } from '../actions/profile.js';
|
||||||
checkEmailAvailability,
|
|
||||||
checkNomAvailability,
|
|
||||||
registerUser,
|
|
||||||
} from '../actions/profile.js';
|
|
||||||
|
|
||||||
import Register from './Register.js';
|
import Register from './Register.js';
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
checkEmail: (email) => dispatch(checkEmailAvailability(email)),
|
checkEmail: (email) => dispatch(checkEmailAvailability(email)),
|
||||||
checkNomDeBid: (nomDeBid) => dispatch(checkNomAvailability(nomDeBid)),
|
checkNomDeBid: (nomDeBid) => dispatch(checkNomAvailability(nomDeBid)),
|
||||||
doRegistration: (user) => dispatch(registerUser(user)),
|
doRegistration: (user) => dispatch(registerUser(user)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(null, mapDispatchToProps)(Register);
|
export default connect(
|
||||||
|
null,
|
||||||
|
mapDispatchToProps,
|
||||||
|
)(Register);
|
||||||
|
|||||||
@@ -4,87 +4,95 @@ import { Text, View } from 'react-native';
|
|||||||
import styles from './Register.styles.js';
|
import styles from './Register.styles.js';
|
||||||
|
|
||||||
export default class Register extends Component {
|
export default class Register extends Component {
|
||||||
|
static get propTypes() {
|
||||||
static get propTypes() {
|
return {
|
||||||
return {
|
checkEmail: PropTypes.func.isRequired,
|
||||||
checkEmail: PropTypes.func.isRequired,
|
checkNomDeBid: PropTypes.func.isRequired,
|
||||||
checkNomDeBid: PropTypes.func.isRequired,
|
doRegistration: PropTypes.func.isRequired,
|
||||||
doRegistration: PropTypes.func.isRequired,
|
// invalidEmail: PropTypes.bool.isRequired,
|
||||||
// invalidEmail: PropTypes.bool.isRequired,
|
// invalidNomDeBid: PropTypes.bool.isRequired,
|
||||||
// invalidNomDeBid: PropTypes.bool.isRequired,
|
};
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
addresses: [],
|
|
||||||
avatar: null,
|
|
||||||
email: null,
|
|
||||||
firstName: null,
|
|
||||||
lastName: null,
|
|
||||||
nomDeBid: null,
|
|
||||||
invalidEmail: false,
|
|
||||||
invalidNomDeBid: false,
|
|
||||||
password: null,
|
|
||||||
phones: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
this._doRegistration = this._doRegistration.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
_doRegistration() {
|
|
||||||
if (!this.isFormComplete()) {
|
|
||||||
console.error('Incomplete form... how did the button become enabled?');
|
|
||||||
alert('Please complete all of the required fields. They have bold labels.');
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.props.doRegistration(this.getUserRegistration());
|
constructor() {
|
||||||
}
|
super(props);
|
||||||
|
|
||||||
_validateEmail() {
|
this.state = {
|
||||||
this.props.checkEmail(this.state.email, (valid) => this.setState('invalidEmail', valid));
|
addresses: [],
|
||||||
}
|
avatar: null,
|
||||||
|
email: null,
|
||||||
|
firstName: null,
|
||||||
|
lastName: null,
|
||||||
|
nomDeBid: null,
|
||||||
|
invalidEmail: false,
|
||||||
|
invalidNomDeBid: false,
|
||||||
|
password: null,
|
||||||
|
phones: [],
|
||||||
|
};
|
||||||
|
|
||||||
_validateNomDeBid() {
|
this._doRegistration = this._doRegistration.bind(this);
|
||||||
this.props.checkNomDeBid(this.state.nomDeBid, (valid) => this.setState('invalidNomDeBid', valid));
|
}
|
||||||
}
|
|
||||||
|
|
||||||
getUserRegistration() {
|
_doRegistration() {
|
||||||
return {
|
if (!this.isFormComplete()) {
|
||||||
addresses: this.state.addresses,
|
console.error('Incomplete form... how did the button become enabled?');
|
||||||
avatar: this.state.avatar,
|
alert('Please complete all of the required fields. They have bold labels.');
|
||||||
email: this.state.email,
|
return;
|
||||||
firstName: this.state.firstName,
|
}
|
||||||
lastName: this.state.lastName,
|
|
||||||
nomDeBid: this.state.nomDeBid,
|
|
||||||
password: this.state.password,
|
|
||||||
phones: this.state.phones,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
isFormComplete() {
|
this.props.doRegistration(this.getUserRegistration());
|
||||||
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() {
|
_validateEmail() {
|
||||||
return (
|
this.props.checkEmail(this.state.email, (valid) => this.setState('invalidEmail', valid));
|
||||||
<View style={styles.container}>
|
}
|
||||||
<Text style={styles.title}>Sign In or Register</Text>
|
|
||||||
<View style={styles.localLogin}>
|
_validateNomDeBid() {
|
||||||
<LocalLogin />
|
this.props.checkNomDeBid(this.state.nomDeBid, (valid) =>
|
||||||
</View>
|
this.setState('invalidNomDeBid', valid),
|
||||||
<View style={styles.services}>
|
);
|
||||||
<FacebookLogin />
|
}
|
||||||
</View>
|
|
||||||
<View style={styles.register}>
|
getUserRegistration() {
|
||||||
<Button onPress={this._doRegistration} />
|
return {
|
||||||
</View>
|
addresses: this.state.addresses,
|
||||||
</View>
|
avatar: this.state.avatar,
|
||||||
);
|
email: this.state.email,
|
||||||
}
|
firstName: this.state.firstName,
|
||||||
|
lastName: this.state.lastName,
|
||||||
|
nomDeBid: this.state.nomDeBid,
|
||||||
|
password: this.state.password,
|
||||||
|
phones: this.state.phones,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<Text style={styles.title}>Sign In or Register</Text>
|
||||||
|
<View style={styles.localLogin}>
|
||||||
|
<LocalLogin />
|
||||||
|
</View>
|
||||||
|
<View style={styles.services}>
|
||||||
|
<FacebookLogin />
|
||||||
|
</View>
|
||||||
|
<View style={styles.register}>
|
||||||
|
<Button onPress={this._doRegistration} />
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,12 @@
|
|||||||
import { StyleSheet } from 'react-native';
|
import { StyleSheet } from 'react-native';
|
||||||
|
|
||||||
export const styles = StyleSheet.create({
|
export default (styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
},
|
},
|
||||||
title: {
|
title: {},
|
||||||
},
|
localLogin: {},
|
||||||
localLogin: {
|
services: {},
|
||||||
},
|
register: {},
|
||||||
services: {
|
}));
|
||||||
},
|
|
||||||
register: {
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -8,31 +8,30 @@ import LocalLogin from '../components/Login/LocalLogin.container.js';
|
|||||||
import styles from './SignInOrRegister.styles.js';
|
import styles from './SignInOrRegister.styles.js';
|
||||||
|
|
||||||
export default class SignInOrRegister extends Component {
|
export default class SignInOrRegister extends Component {
|
||||||
|
constructor() {
|
||||||
|
super(props);
|
||||||
|
|
||||||
constructor() {
|
this._doRegistration = this._doRegistration.bind(this);
|
||||||
super(props);
|
}
|
||||||
|
|
||||||
this._doRegistration = this._doRegistration.bind(this);
|
_doRegistration() {
|
||||||
}
|
this.props.navigation.navigate('Register');
|
||||||
|
}
|
||||||
|
|
||||||
_doRegistration() {
|
render() {
|
||||||
this.props.navigation.navigate('Register');
|
return (
|
||||||
}
|
<View style={styles.container}>
|
||||||
|
<Text style={styles.title}>Sign In or Register</Text>
|
||||||
render() {
|
<View style={styles.localLogin}>
|
||||||
return (
|
<LocalLogin />
|
||||||
<View style={styles.container}>
|
</View>
|
||||||
<Text style={styles.title}>Sign In or Register</Text>
|
<View style={styles.services}>
|
||||||
<View style={styles.localLogin}>
|
<FacebookLogin />
|
||||||
<LocalLogin />
|
</View>
|
||||||
</View>
|
<View style={styles.register}>
|
||||||
<View style={styles.services}>
|
<Button title="Signup with Email" onPress={this._doRegistration} />
|
||||||
<FacebookLogin />
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<View style={styles.register}>
|
);
|
||||||
<Button title="Signup with Email" onPress={this._doRegistration} />
|
}
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import { StyleSheet } from 'react-native';
|
import { StyleSheet } from 'react-native';
|
||||||
|
|
||||||
export const styles = StyleSheet.create({
|
export default (styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
backgroundColor: '#F5FCFF',
|
backgroundColor: '#F5FCFF',
|
||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
margin: 10,
|
margin: 10,
|
||||||
}
|
},
|
||||||
});
|
}));
|
||||||
|
|||||||
@@ -1,33 +1,26 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import {
|
import { StyleSheet, Text, View } from 'react-native';
|
||||||
StyleSheet,
|
|
||||||
Text,
|
|
||||||
View,
|
|
||||||
} from 'react-native';
|
|
||||||
|
|
||||||
export default class Ticketing extends Component {
|
export default class Ticketing extends Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<Text style={styles.title}>
|
<Text style={styles.title}>Ticketing</Text>
|
||||||
Ticketing
|
</View>
|
||||||
</Text>
|
);
|
||||||
</View>
|
}
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
backgroundColor: '#F5FCFF',
|
backgroundColor: '#F5FCFF',
|
||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
margin: 10,
|
margin: 10,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ import { createSelector } from 'reselect';
|
|||||||
const getState = (state) => state;
|
const getState = (state) => state;
|
||||||
|
|
||||||
export const getActiveEventId = createSelector(
|
export const getActiveEventId = createSelector(
|
||||||
[getState],
|
[getState],
|
||||||
(state) => state.get('activeEvent'),
|
(state) => state.get('activeEvent'),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const hasActiveEvent = createSelector(
|
export const hasActiveEvent = createSelector(
|
||||||
[getActiveEventId],
|
[getActiveEventId],
|
||||||
(eventId) => !!eventId,
|
(eventId) => !!eventId,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -6,28 +6,30 @@ export const getItemBidCount = (state, itemId) => state.getIn(['auctions', itemI
|
|||||||
|
|
||||||
export const getItemPrice = (state, itemId) => state.getIn(['auctions', itemId, 'currentPrice'], 0);
|
export const getItemPrice = (state, itemId) => state.getIn(['auctions', itemId, 'currentPrice'], 0);
|
||||||
|
|
||||||
export const isBiddingItem = (state, itemId) => state.getIn(['auctions', itemId, 'isBidding'], false);
|
export const isBiddingItem = (state, itemId) =>
|
||||||
|
state.getIn(['auctions', itemId, 'isBidding'], false);
|
||||||
|
|
||||||
export const isWinningItem = (state, itemId) => state.getIn(['auctions', itemId, 'isWinning'], false);
|
export const isWinningItem = (state, itemId) =>
|
||||||
|
state.getIn(['auctions', itemId, 'isWinning'], false);
|
||||||
|
|
||||||
export const getAuctionStatus = (state, itemId) => state.getIn(['actions', itemId], false);
|
export const getAuctionStatus = (state, itemId) => state.getIn(['actions', itemId], false);
|
||||||
|
|
||||||
export const getAuctionStatuses = createSelector(
|
export const getAuctionStatuses = createSelector(
|
||||||
[getState],
|
[getState],
|
||||||
(state) => state.get('actions') || new Map(),
|
(state) => state.get('actions') || new Map(),
|
||||||
);
|
);
|
||||||
|
|
||||||
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),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,6 +3,6 @@ import { createSelector } from 'reselect';
|
|||||||
const getState = (state) => state;
|
const getState = (state) => state;
|
||||||
|
|
||||||
export const getAuthToken = createSelector(
|
export const getAuthToken = createSelector(
|
||||||
[getState],
|
[getState],
|
||||||
(state) => state.get('auth'),
|
(state) => state.get('auth'),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -8,26 +8,26 @@ const getState = (state) => state;
|
|||||||
export const getEventById = (state, eventId) => state.getIn(['events', eventId], false);
|
export const getEventById = (state, eventId) => state.getIn(['events', eventId], false);
|
||||||
|
|
||||||
export const getEvents = createSelector(
|
export const getEvents = createSelector(
|
||||||
[getState],
|
[getState],
|
||||||
(state) => state.get('events') || new Map(),
|
(state) => state.get('events') || new Map(),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getActiveEvent = createSelector(
|
export const getActiveEvent = createSelector(
|
||||||
[getActiveEventId, getEvents],
|
[getActiveEventId, getEvents],
|
||||||
(eventId, eventsAsMap) => eventId ? eventsAsMap.get(eventId) : null,
|
(eventId, eventsAsMap) => (eventId ? eventsAsMap.get(eventId) : null),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getDefaultEvent = createSelector(
|
export const getDefaultEvent = createSelector(
|
||||||
[getEvents],
|
[getEvents],
|
||||||
(eventsAsMap) => eventsAsMap.first(),
|
(eventsAsMap) => eventsAsMap.first(),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getEventsAsList = createSelector(
|
export const getEventsAsList = createSelector(
|
||||||
[getEvents],
|
[getEvents],
|
||||||
(eventsAsMap) => eventsAsMap.toList(),
|
(eventsAsMap) => eventsAsMap.toList(),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const hasMultipleEvents = createSelector(
|
export const hasMultipleEvents = createSelector(
|
||||||
[getEvents],
|
[getEvents],
|
||||||
(eventsAsMap) => eventsAsMap.size > 1,
|
(eventsAsMap) => eventsAsMap.size > 1,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -8,61 +8,61 @@ const getState = (state) => state;
|
|||||||
export const getItem = (state, itemId) => state.getIn(['items', itemId], false);
|
export const getItem = (state, itemId) => state.getIn(['items', itemId], false);
|
||||||
|
|
||||||
export const getItems = createSelector(
|
export const getItems = createSelector(
|
||||||
[getState],
|
[getState],
|
||||||
(state) => state.get('items') || new Map(),
|
(state) => state.get('items') || new Map(),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getItemsAsList = createSelector(
|
export const getItemsAsList = createSelector(
|
||||||
[getItems],
|
[getItems],
|
||||||
(itemsAsMap) => itemsAsMap.toList(),
|
(itemsAsMap) => itemsAsMap.toList(),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getAuctionItems = createSelector(
|
export const getAuctionItems = createSelector(
|
||||||
[getState],
|
[getState],
|
||||||
(state) => state.get('items').filter(i => i.type === 'auction') || new Map(),
|
(state) => state.get('items').filter((i) => i.type === 'auction') || new Map(),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getAuctionItemsAsList = createSelector(
|
export const getAuctionItemsAsList = createSelector(
|
||||||
[getAuctionItems],
|
[getAuctionItems],
|
||||||
(auctionItemsAsMap) => auctionItemsAsMap.toList(),
|
(auctionItemsAsMap) => auctionItemsAsMap.toList(),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getAuctionItemsUserIsBidding = createSelector(
|
export const getAuctionItemsUserIsBidding = createSelector(
|
||||||
[getAuctionItems, getMyBidItemIds],
|
[getAuctionItems, getMyBidItemIds],
|
||||||
(items, myBids) => items.filter(i => myBids.indexOf(i.id)) || new Map(),
|
(items, myBids) => items.filter((i) => myBids.indexOf(i.id)) || new Map(),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getAuctionItemsUserIsBiddingAsList = createSelector(
|
export const getAuctionItemsUserIsBiddingAsList = createSelector(
|
||||||
[getAuctionItemsUserIsBidding],
|
[getAuctionItemsUserIsBidding],
|
||||||
(auctionItemsAsMap) => auctionItemsAsMap.toList(),
|
(auctionItemsAsMap) => auctionItemsAsMap.toList(),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getAuctionItemsUserIsWinning = createSelector(
|
export const getAuctionItemsUserIsWinning = createSelector(
|
||||||
[getAuctionItemsUserIsBidding, getMyWinningItemIds],
|
[getAuctionItemsUserIsBidding, getMyWinningItemIds],
|
||||||
(items, myWins) => items.filter(i => myWins.indexOf(i.id)) || new Map(),
|
(items, myWins) => items.filter((i) => myWins.indexOf(i.id)) || new Map(),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getAuctionItemsUserIsWinningAsList = createSelector(
|
export const getAuctionItemsUserIsWinningAsList = createSelector(
|
||||||
[getAuctionItemsUserIsWinning],
|
[getAuctionItemsUserIsWinning],
|
||||||
(auctionItemsAsMap) => auctionItemsAsMap.toList(),
|
(auctionItemsAsMap) => auctionItemsAsMap.toList(),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getAuctionItemsWithNoBids = createSelector(
|
export const getAuctionItemsWithNoBids = createSelector(
|
||||||
[getAuctionItems, getItemsIdsWithNoBids],
|
[getAuctionItems, getItemsIdsWithNoBids],
|
||||||
(items, noBids) => items.filter(i => noBids.indexOf(i.id)) || new Map(),
|
(items, noBids) => items.filter((i) => noBids.indexOf(i.id)) || new Map(),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getAuctionItemsWithNoBidsAsList = createSelector(
|
export const getAuctionItemsWithNoBidsAsList = createSelector(
|
||||||
[getAuctionItemsWithNoBids],
|
[getAuctionItemsWithNoBids],
|
||||||
(auctionItemsAsMap) => auctionItemsAsMap.toList(),
|
(auctionItemsAsMap) => auctionItemsAsMap.toList(),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getTicketItems = createSelector(
|
export const getTicketItems = createSelector(
|
||||||
[getState],
|
[getState],
|
||||||
(state) => state.get('items').filter(i => i.type === 'ticket') || new Map(),
|
(state) => state.get('items').filter((i) => i.type === 'ticket') || new Map(),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getTicketItemsAsList = createSelector(
|
export const getTicketItemsAsList = createSelector(
|
||||||
[getTicketItems],
|
[getTicketItems],
|
||||||
(ticketItemsAsMap) => ticketItemsAsMap.toList(),
|
(ticketItemsAsMap) => ticketItemsAsMap.toList(),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,21 +4,21 @@ import { createSelector } from 'reselect';
|
|||||||
const getState = (state) => state;
|
const getState = (state) => state;
|
||||||
|
|
||||||
export const getProfile = createSelector(
|
export const getProfile = createSelector(
|
||||||
[getState],
|
[getState],
|
||||||
(state) => state.get('profile'),
|
(state) => state.get('profile'),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getNomDeBid = createSelector(
|
export const getNomDeBid = createSelector(
|
||||||
[getProfile],
|
[getProfile],
|
||||||
(profile) => profile.get('nomDeBid'),
|
(profile) => profile.get('nomDeBid'),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getProfileAvatarUrl = createSelector(
|
export const getProfileAvatarUrl = createSelector(
|
||||||
[getProfile],
|
[getProfile],
|
||||||
(profile) => profile.get('avatar'),
|
(profile) => profile.get('avatar'),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const isAllowedToBid = createSelector(
|
export const isAllowedToBid = createSelector(
|
||||||
[getProfile],
|
[getProfile],
|
||||||
(profile) => profile.get('isAllowedToBid'),
|
(profile) => profile.get('isAllowedToBid'),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ import thunk from 'redux-thunk';
|
|||||||
|
|
||||||
import rootReducer from '../reducers/index.js';
|
import rootReducer from '../reducers/index.js';
|
||||||
|
|
||||||
const composeEnhancers = composeWithDevTools({ port: 8000, realtime: true, suppressConnectErrors: false });
|
const composeEnhancers = composeWithDevTools({
|
||||||
|
port: 8000,
|
||||||
|
realtime: true,
|
||||||
|
suppressConnectErrors: false,
|
||||||
|
});
|
||||||
|
|
||||||
export const store = createStore(
|
export const store = createStore(rootReducer, Map(), composeEnhancers(applyMiddleware(thunk)));
|
||||||
rootReducer,
|
|
||||||
Map(),
|
|
||||||
composeEnhancers(applyMiddleware(thunk)),
|
|
||||||
);
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
presets: ['module:metro-react-native-babel-preset'],
|
presets: ['module:metro-react-native-babel-preset'],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,11 +11,11 @@ import { name as appName } from './app.json';
|
|||||||
import { store } from './app/store/index.js';
|
import { store } from './app/store/index.js';
|
||||||
|
|
||||||
const connectedApp = () => {
|
const connectedApp = () => {
|
||||||
return (
|
return (
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<App />
|
<App />
|
||||||
</Provider>
|
</Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
AppRegistry.registerComponent(appName, () => connectedApp);
|
AppRegistry.registerComponent(appName, () => connectedApp);
|
||||||
|
|||||||
10
index.ios.js
10
index.ios.js
@@ -11,11 +11,11 @@ import { name as appName } from './app.json';
|
|||||||
import { store } from './app/store/index.js';
|
import { store } from './app/store/index.js';
|
||||||
|
|
||||||
const connectedApp = () => {
|
const connectedApp = () => {
|
||||||
return (
|
return (
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<App />
|
<App />
|
||||||
</Provider>
|
</Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
AppRegistry.registerComponent(appName, () => connectedApp);
|
AppRegistry.registerComponent(appName, () => connectedApp);
|
||||||
|
|||||||
10
index.js
10
index.js
@@ -11,11 +11,11 @@ import { name as appName } from './app.json';
|
|||||||
import { store } from './app/store/index.js';
|
import { store } from './app/store/index.js';
|
||||||
|
|
||||||
const connectedApp = () => {
|
const connectedApp = () => {
|
||||||
return (
|
return (
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<App />
|
<App />
|
||||||
</Provider>
|
</Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
AppRegistry.registerComponent(appName, () => connectedApp);
|
AppRegistry.registerComponent(appName, () => connectedApp);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user