- Initial commit
This commit is contained in:
52
app/App.js
Normal file
52
app/App.js
Normal file
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Sample React Native App
|
||||
* https://github.com/facebook/react-native
|
||||
*
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import React, {Fragment} from 'react';
|
||||
import {
|
||||
SafeAreaView,
|
||||
StyleSheet,
|
||||
ScrollView,
|
||||
View,
|
||||
Text,
|
||||
StatusBar,
|
||||
} from 'react-native';
|
||||
|
||||
import { Tabs } from './router.js';
|
||||
|
||||
const App = () => {
|
||||
return <Tabs />;
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
scrollView: {
|
||||
backgroundColor: Colors.lighter,
|
||||
},
|
||||
body: {
|
||||
backgroundColor: Colors.white,
|
||||
},
|
||||
sectionContainer: {
|
||||
marginTop: 32,
|
||||
paddingHorizontal: 24,
|
||||
},
|
||||
sectionTitle: {
|
||||
fontSize: 24,
|
||||
fontWeight: '600',
|
||||
color: Colors.black,
|
||||
},
|
||||
sectionDescription: {
|
||||
marginTop: 8,
|
||||
fontSize: 18,
|
||||
fontWeight: '400',
|
||||
color: Colors.dark,
|
||||
},
|
||||
highlight: {
|
||||
fontWeight: '700',
|
||||
},
|
||||
});
|
||||
|
||||
export default App;
|
||||
29
app/actions/index.js
Normal file
29
app/actions/index.js
Normal file
@@ -0,0 +1,29 @@
|
||||
import { getEndpointUrl } from '../api/index.js';
|
||||
import {
|
||||
EVENTS_LOADED,
|
||||
GET_EVENTS,
|
||||
GET_ITEMS,
|
||||
ITEMS_LOADED,
|
||||
} from '../constants/actionTypes.js';
|
||||
import { API_ENDPOINTS } from '../constants/constants.js';
|
||||
|
||||
export const getEvents = () => (dispatch) => {
|
||||
return fetch(getEndpointUrl[API_ENDPOINTS.GET_EVENTS])
|
||||
.then(response => response.json())
|
||||
.then(payload => {
|
||||
dispatch({ type: EVENTS_LOADED, payload });
|
||||
});
|
||||
};
|
||||
|
||||
export const getItems = () => (dispatch, getState) => {
|
||||
const { activeEvent } = getState();
|
||||
let apiUrl = getEndpointUrl[API_ENDPOINTS.GET_ITEMS];
|
||||
apiUrl = apiUrl.replace(/:event_id/, activeEvent);
|
||||
|
||||
return fetch(apiUrl)
|
||||
.then(response => response.json())
|
||||
.then(payload => {
|
||||
dispatch({ type: ITEMS_LOADED, payload });
|
||||
});
|
||||
};
|
||||
|
||||
37
app/api/index.js
Normal file
37
app/api/index.js
Normal file
@@ -0,0 +1,37 @@
|
||||
const apiUrl = 'http://localhost:3001';
|
||||
|
||||
const endpoints = {
|
||||
// Events and Items
|
||||
GET_EVENTS: '/events',
|
||||
GET_ITEMS: '/items?eventId=:event_id',
|
||||
|
||||
// Auction Interactions
|
||||
GET_STATUS: '/auction',
|
||||
PLACE_BID: '/bids/:item_id',
|
||||
PURCHASE_ITEM: '/sales',
|
||||
|
||||
// User/Profile
|
||||
USER_SIGNUP: '/signup',
|
||||
USER_PROFILE: '/users/:user_id',
|
||||
|
||||
// Services
|
||||
APPLE_SIGNUP: '/auth/apple/login',
|
||||
APPLE_LINK: '/auth/apple/link',
|
||||
FACEBOOK_SIGNUP: '/auth/facebook/login',
|
||||
FACEBOOK_LINK: '/auth/facebook/link',
|
||||
GOOGLE_SIGNUP: '/auth/google/login',
|
||||
GOOGLE_LINK: '/auth/google/link',
|
||||
};
|
||||
|
||||
const cacheBuster = () => {
|
||||
const timestamp = String(Date.now());
|
||||
return `?buster=${timestamp}`;
|
||||
};
|
||||
|
||||
export const getEndpointUrl = (endpoint) => {
|
||||
if (!endpoints[endpoint]) {
|
||||
return throw new Error('Invalid API endpoint specified');
|
||||
}
|
||||
|
||||
return `${apiUrl}${endpoints[endpoint]}${cacheBuster()}`;
|
||||
};
|
||||
24
app/components/Auction/AuctionPriceAndBidCount.js
Normal file
24
app/components/Auction/AuctionPriceAndBidCount.js
Normal file
@@ -0,0 +1,24 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { formatPrice } from '../../library/helpers.js';
|
||||
|
||||
import {
|
||||
StyleSheet,
|
||||
Text,
|
||||
} from 'react-native';
|
||||
|
||||
const AuctionPriceAndBidCount = ({ bidCount, currentPrice }) => {
|
||||
return (
|
||||
<Text style={styles.currentPriceAndBidCount} numberOfLines={1}>
|
||||
{`${formatPrice(currentPrice)} (${bidCount} bids)`}
|
||||
</Text>
|
||||
);
|
||||
};
|
||||
|
||||
AuctionPriceAndBidCount.propTypes = {
|
||||
bidCount: PropTypes.number.isRequired,
|
||||
currentPrice: PropTypes.number.isRequired,
|
||||
};
|
||||
|
||||
export default AuctionPriceAndBidCount;
|
||||
44
app/components/Auction/BidStatus.js
Normal file
44
app/components/Auction/BidStatus.js
Normal file
@@ -0,0 +1,44 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import {
|
||||
StyleSheet,
|
||||
View,
|
||||
} from 'react-native';
|
||||
|
||||
const BidStatus = ({ bidCount, currentPrice, isBidding, isWinning }) => {
|
||||
if (!isBidding) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const statusBarStyle = isWinning
|
||||
? [ styles.bidStatus, styes.isWinning ]
|
||||
: [ styles.bidStatus, styles.isOutbid ];
|
||||
|
||||
return (
|
||||
<Text style={statusBarStyle} numberOfLines={1}>
|
||||
{`${currentPrice} (${bidCount} bids)`}
|
||||
</Text>
|
||||
);
|
||||
};
|
||||
|
||||
BidStatus.propTypes = {
|
||||
bidCount: PropTypes.number.isRequired,
|
||||
currentPrice: PropTypes.number.isRequired,
|
||||
isBidding: PropTypes.bool.isRequired,
|
||||
isWinning: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
bidStatus: {
|
||||
color: '#fff',
|
||||
},
|
||||
isWinning: {
|
||||
backgroundColor: '#F00',
|
||||
},
|
||||
isOutbid: {
|
||||
backgroundColor: '#0F0',
|
||||
},
|
||||
});
|
||||
|
||||
export default BidStatus;
|
||||
0
app/components/Item/Grid.js
Normal file
0
app/components/Item/Grid.js
Normal file
164
app/components/Item/List.js
Normal file
164
app/components/Item/List.js
Normal file
@@ -0,0 +1,164 @@
|
||||
import React, { Component } from 'react';
|
||||
import {
|
||||
StyleSheet,
|
||||
TouchableOpacity,
|
||||
Text,
|
||||
Image,
|
||||
View
|
||||
} from 'react-native';
|
||||
|
||||
import AuctionPriceAndBidCount from '../../containers/Auction/AuctionPriceAndBidCount.js';
|
||||
import BidStatus from '../../containers/Auction/BidStatus.js';
|
||||
|
||||
import { ITEM_TYPES } from '../../constants/constants.js';
|
||||
import { formatPrice, getAuctionTime } from '../../library/helpers.js';
|
||||
|
||||
export default class ItemRow extends Component {
|
||||
static get propTypes() {
|
||||
return {
|
||||
description: PropTypes.string,
|
||||
donor: PropTypes.string,
|
||||
end: PropTypes.string.isRequired,
|
||||
id: PropTypes.string.isRequired,
|
||||
images: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
url: PropTypes.string,
|
||||
}),
|
||||
),
|
||||
start: PropTytpes.string.isRequired,
|
||||
startPrice: PropTypes.number,
|
||||
subtitle: PropTypes.string,
|
||||
title: PropTypes.string.isRequired,
|
||||
type: PropTypes.string.isRequired,
|
||||
};
|
||||
}
|
||||
|
||||
_getBidTime = () => {
|
||||
const { end, start } = this.props;
|
||||
return getAuctionTime({ end, start });
|
||||
}
|
||||
|
||||
_viewItemDetail = () => {
|
||||
const { id } = this.props.details;
|
||||
this.props.navigation.navigate('Item', { id });
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
description,
|
||||
donor,
|
||||
end,
|
||||
images,
|
||||
start,
|
||||
startPrice,
|
||||
subtitle,
|
||||
title,
|
||||
type,
|
||||
} = this.props;
|
||||
|
||||
return(
|
||||
<TouchableOpacity onPress={this._viewItemDetail}>
|
||||
<View style={styles.rowContainer}>
|
||||
<Image
|
||||
source={{uri: images[0].url}}
|
||||
style={styles.image}
|
||||
resizeMode="contain"
|
||||
/>
|
||||
<View style={styles.rowText}>
|
||||
{type === ITEM_TYPES.AUCTION && <BidStatus id={item.id} />}
|
||||
<Text style={styles.title} numberOfLines={2} ellipsizeMode={'tail'}>
|
||||
{title}
|
||||
</Text>
|
||||
<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 id={item.id} />
|
||||
) : (
|
||||
<Text style={styles.price} numberOfLines={1} ellipsizeMode={'tail'}>
|
||||
{formatPrice(startPrice)}
|
||||
</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({
|
||||
description: {
|
||||
color: '#777',
|
||||
fontSize: 14,
|
||||
marginTop: 5,
|
||||
paddingLeft: 10,
|
||||
paddingRight: 10,
|
||||
},
|
||||
donor: {
|
||||
color: '#777',
|
||||
fontSize: 14,
|
||||
marginTop: 5,
|
||||
paddingLeft: 10,
|
||||
},
|
||||
image: {
|
||||
flex: 1,
|
||||
height: undefined,
|
||||
width: undefined,
|
||||
},
|
||||
price: {
|
||||
color: '#777',
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
paddingLeft: 10,
|
||||
paddingTop: 5,
|
||||
},
|
||||
rowContainer: {
|
||||
backgroundColor: '#FFF',
|
||||
borderRadius: 4,
|
||||
flexDirection: 'row',
|
||||
height: 100,
|
||||
marginRight: 10,
|
||||
marginLeft: 10,
|
||||
marginTop: 10,
|
||||
padding: 10,
|
||||
shadowColor: '#CCC',
|
||||
shadowOffset:{ width: 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,
|
||||
},
|
||||
});
|
||||
43
app/constants/actionTypes.js
Normal file
43
app/constants/actionTypes.js
Normal file
@@ -0,0 +1,43 @@
|
||||
export const GET_EVENTS = 'GET_EVENTS';
|
||||
export const EVENTS_LOADED = 'EVENTS_LOADED';
|
||||
export const EVENTS_LOAD_FAILED = 'EVENTS_LOAD_FAILED';
|
||||
|
||||
export const GET_ITEMS = 'GET_ITEMS';
|
||||
export const ITEMS_LOADED = 'ITEMS_LOADED';
|
||||
export const ITEMS_LOAD_FAILED = 'ITEMS_LOAD_FAILED';
|
||||
|
||||
export const UPDATE_AUCTIONS = 'UPDATE_AUCTIONS';
|
||||
|
||||
export const SET_TICKET_PURCHASE_FLOW = 'SET_TICKET_PURCHASE_FLOW';
|
||||
|
||||
export const PLACE_BID = 'PLACE_BID';
|
||||
|
||||
export const DO_LOGIN = 'DO_LOGIN';
|
||||
export const DO_LOGOUT = 'DO_LOOUT';
|
||||
|
||||
export const DO_SIGNUP = 'DO_SIGNUP';
|
||||
|
||||
export const DO_SIGNUP_APPLE = 'DO_SIGNUP_APPLE';
|
||||
export const DO_SIGNUP_FACEBOOK = 'DO_SIGNUP_FACEBOOK';
|
||||
export const DO_SIGNUP_GOOGLE = 'DO_SIGNUP_GOOGLE';
|
||||
|
||||
export const DO_LINK_APPLE = 'DO_LINK_APPLE';
|
||||
export const DO_LINK_FACEBOOK = 'DO_LINK_FACEBOOK';
|
||||
export const DO_LINK_GOOGLE = 'DO_LINK_GOOGLE';
|
||||
|
||||
export const LINK_APPLE_FAILURE = 'LINK_APPLE_FAILURE';
|
||||
export const LINK_APPLE_SUCCESS = 'LINK_APPLE_SUCCESS';
|
||||
|
||||
export const LINK_FACEBOOK_FAILURE = 'LINK_FACEBOOK_FAILURE';
|
||||
export const LINK_FACEBOOK_SUCCESS = 'LINK_FACEBOOK_SUCCESS';
|
||||
|
||||
export const LINK_GOOGLE_FAILURE = 'LINK_GOOGLE_FAILURE';
|
||||
export const LINK_GOOGLE_SUCCESS = 'LINK_GOOGLE_SUCCESS';
|
||||
|
||||
export const UPDATE_PROFILE = 'UPDATE_PROFILE';
|
||||
|
||||
export const SET_NOM_DE_BID = 'SET_NOM_DE_BID';
|
||||
export const SET_PASSWORD = 'SET_PASSWORD';
|
||||
|
||||
export const ADD_PAYMENT_DATA = 'ADD_PAYMENT_DATA';
|
||||
export const DO_CHECKOUT = 'DO_CHECKOUT';
|
||||
41
app/constants/constants.js
Normal file
41
app/constants/constants.js
Normal file
@@ -0,0 +1,41 @@
|
||||
export const ITEM_TYPES = {
|
||||
AUCTION: 'auction',
|
||||
DONATION: 'donation',
|
||||
EVENT: 'event',
|
||||
MEMBERSHIP: 'membership',
|
||||
POPUP: 'popup',
|
||||
RAFFLE: 'raffle',
|
||||
TICKET: 'ticket',
|
||||
};
|
||||
|
||||
export const SORT_MODES = {
|
||||
BIDDERS_ASC: 'BIDDERS_ASC',
|
||||
BIDDERS_DSC: 'BIDDERS_DSC',
|
||||
ENDING_ASC: 'ENDING_ASC',
|
||||
ENDING_DSC: 'ENDING_DSC',
|
||||
PRICE_ASC: 'PRICE_ASC',
|
||||
PRICE_DSC: 'PRICE_DSC',
|
||||
TITLE_ASC: 'TITLE_ASC',
|
||||
TITLE_DSC: 'TITLE_DSC',
|
||||
};
|
||||
|
||||
export const VIEW_MODES = {
|
||||
LIST: 'LIST',
|
||||
GRID: 'GRID',
|
||||
};
|
||||
|
||||
export const API_ENDPOINTS = {
|
||||
GET_EVENTS: 'GET_EVENTS',
|
||||
GET_ITEMS: 'GET_ITEMS',
|
||||
GET_STATUS: 'GET_STATUS',
|
||||
PLACE_BID: 'PLACE_BID',
|
||||
PURCHASE_ITEM: 'PURCHASE_ITEM',
|
||||
USER_SIGNUP: 'USER_SIGNUP',
|
||||
USER_PROFILE: 'USER_PROFILE',
|
||||
APPLE_SIGNUP: 'APPLE_SIGNUP',
|
||||
APPLE_LINK: 'APPLE_LINK',
|
||||
FACEBOOK_SIGNUP: 'FACEBOOK_SIGNUP',
|
||||
FACEBOOK_LINK: 'FACEBOOK_LINK',
|
||||
GOOGLE_SIGNUP: 'GOOGLE_SIGNUP',
|
||||
GOOGLE_LINK: 'GOOGLE_LINK',
|
||||
};
|
||||
14
app/containers/Auction/AuctionPriceAndBidCount.js
Normal file
14
app/containers/Auction/AuctionPriceAndBidCount.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import AuctionPriceAndBidCount from '../../components/Auction/AuctionPriceAndBidCount.js';
|
||||
|
||||
function mapStateToProps(state, ownProps) {
|
||||
const { bidCount, currentPrice } = getAuctionItemStatus(state, ownProps.id);
|
||||
|
||||
return {
|
||||
bidCount,
|
||||
currentPrice,
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, null)(AuctionPriceAndBidCount);
|
||||
21
app/containers/Auction/BidStatus.js
Normal file
21
app/containers/Auction/BidStatus.js
Normal file
@@ -0,0 +1,21 @@
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import AuctionPriceAndBidCount from '../../components/Auction/BidStatus.js';
|
||||
|
||||
function mapStateToProps(state, ownProps) {
|
||||
const {
|
||||
bidCount,
|
||||
currentPrice,
|
||||
isBidding,
|
||||
isWinning,
|
||||
} = getAuctionItemStatus(state, ownProps.id);
|
||||
|
||||
return {
|
||||
bidCount,
|
||||
currentPrice,
|
||||
isBidding,
|
||||
isWinning,
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, null)(AuctionPriceAndBidCount);
|
||||
0
app/fixtures/event.js
Normal file
0
app/fixtures/event.js
Normal file
0
app/fixtures/item.js
Normal file
0
app/fixtures/item.js
Normal file
64
app/library/helpers.js
Normal file
64
app/library/helpers.js
Normal file
@@ -0,0 +1,64 @@
|
||||
import numeral from 'numeral';
|
||||
|
||||
export const formatPrice = (price, format = '$ 0,0[.]00') => {
|
||||
return numeral(price).format(format);
|
||||
};
|
||||
|
||||
export const getAuctionTime = ({ end, start }) => {
|
||||
const now = new Date();
|
||||
const compareToEnd = new Date(end);
|
||||
const compareToStart = new Date(start);
|
||||
|
||||
let delta;
|
||||
if (now < start) {
|
||||
delta = start - now;
|
||||
return 'Bidding starts in ${parseTimeDifferential(delta)}';
|
||||
}
|
||||
|
||||
if (now > start && now < end) {
|
||||
delta = end - now;
|
||||
return 'Bidding ends in ${parseTimeDifferential(delta)}';
|
||||
}
|
||||
|
||||
return 'Bidding has ended';
|
||||
};
|
||||
|
||||
export const parseHumanReadableTimeDifferential = (delta) => {
|
||||
const oneMinute = 60 * 1000;
|
||||
const oneHour = oneMinute * 60;
|
||||
const oneDay = oneHour * 24;
|
||||
const oneWeek = oneDay * 7;
|
||||
const oneMonth = oneWeek * 4;
|
||||
|
||||
let compare = delta / oneMonth;
|
||||
if (compare >= 1) {
|
||||
compare = Math.floor(compare);
|
||||
return `${compare} month${compare > 1 ? 's' : ''}`;
|
||||
}
|
||||
|
||||
compare = delta / oneWeek;
|
||||
if (compare >= 1) {
|
||||
compare = Math.floor(compare);
|
||||
return `${compare} week${compare > 1 ? 's' : ''}`;
|
||||
}
|
||||
|
||||
compare = delta / oneDay;
|
||||
if (compare > 1) {
|
||||
compare = Math.floor(compare);
|
||||
return `${compare} day${compare > 1 ? 's' : ''}`;
|
||||
}
|
||||
|
||||
compare = delta / oneHour;
|
||||
if (compare > 1) {
|
||||
compare = Math.floor(compare);
|
||||
return `${compare} hour${compare > 1 ? 's' : ''}`;
|
||||
}
|
||||
|
||||
compare = delta / oneMinute;
|
||||
if (compare > 1) {
|
||||
compare = Math.floor(compare);
|
||||
return `${compare} minute${compare > 1 ? 's' : ''}`;
|
||||
}
|
||||
|
||||
return 'less than a minute';
|
||||
};
|
||||
17
app/reducers/events.js
Normal file
17
app/reducers/events.js
Normal file
@@ -0,0 +1,17 @@
|
||||
import { EVENTS_LOADED, GET_EVENTS } from '../constants/actionTypes.js';
|
||||
|
||||
export const events = (state = {}, action) => {
|
||||
switch (action.type) {
|
||||
case GET_EVENTS:
|
||||
return Object.assign({}, state, {
|
||||
isFetching: true,
|
||||
});
|
||||
case EVENTS_LOADED:
|
||||
return Object.assign({}, state, {
|
||||
events: action.payload,
|
||||
isFetching: false,
|
||||
});
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
19
app/reducers/index.js
Normal file
19
app/reducers/index.js
Normal file
@@ -0,0 +1,19 @@
|
||||
import { combineReducers } from 'redux';
|
||||
|
||||
import { events } from './events.js';
|
||||
import { items } from './items.js';
|
||||
|
||||
const initialState = {
|
||||
auction: {},
|
||||
cart: [],
|
||||
isFetching: false,
|
||||
items: [],
|
||||
profile: {},
|
||||
};
|
||||
|
||||
const rootReducer = combineReducers({
|
||||
events,
|
||||
items,
|
||||
});
|
||||
|
||||
export default rootReducer;
|
||||
17
app/reducers/items.js
Normal file
17
app/reducers/items.js
Normal file
@@ -0,0 +1,17 @@
|
||||
import { ITEMS_LOADED, GET_ITEMS } from '../constants/actionTypes.js';
|
||||
|
||||
export const items = (state = {}, action) => {
|
||||
switch (action.type) {
|
||||
case GET_ITEMS:
|
||||
return Object.assign({}, state, {
|
||||
isFetching: true,
|
||||
});
|
||||
case ITEMS_LOADED:
|
||||
return Object.assign({}, state, {
|
||||
items: action.payload,
|
||||
isFetching: false,
|
||||
});
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
144
app/router.js
Normal file
144
app/router.js
Normal file
@@ -0,0 +1,144 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Dimensions, Platform } from 'react-native';
|
||||
import { createBottomTabNavigator, createStackNavigator } from 'react-navigation';
|
||||
import { Icon } from 'react-native-elements';
|
||||
|
||||
import Auction from './screens/Auction.js';
|
||||
import Checkout from './screens/Checkout.js';
|
||||
import Event from './screens/Event.js';
|
||||
import Events from './screens/Events.js';
|
||||
import ImageDetail from './screens/ImageDetail.js';
|
||||
import Item from './screens/Item.js';
|
||||
import Marketplace from './screens/Marketplace.js';
|
||||
import Profile from './screens/Profile.js';
|
||||
|
||||
let screen = Dimensions.get('window');
|
||||
|
||||
export const Tabs = createBottomTabNavigator({
|
||||
'Event': {
|
||||
screen: Event,
|
||||
navigationOptions: {
|
||||
tabBarLabel: 'Event',
|
||||
tabBarIcon: ({ tintColor }) => <Icon name="black-tie" type="fontawesome" size={28} color={tintColor} />,
|
||||
},
|
||||
},
|
||||
'Auction': {
|
||||
screen: Auction,
|
||||
navigationOptions: {
|
||||
tabBarLabel: 'Silent Auction',
|
||||
tabBarIcon: ({ tintColor }) => <Icon name="gavel" type="fontawesome" size={28} color={tintColor} />,
|
||||
},
|
||||
},
|
||||
'Bazaar': {
|
||||
screen: Marketplace,
|
||||
navigationOptions: {
|
||||
tabBarLabel: 'Bazaar',
|
||||
tabBarIcon: ({ tintColor }) => <Icon name="shopping-store" type="fontisto" size={28} color={tintColor} />,
|
||||
},
|
||||
},
|
||||
'Profile': {
|
||||
screen: Profile,
|
||||
navigationOptions: {
|
||||
tabBarLabel: 'Profile',
|
||||
tabBarIcon: ({ tintColor }) => <Icon name="ios-person-outline" type="ionicon" size={28} color={tintColor} />,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const AuctionStack = createStackNavigator({
|
||||
Auction: {
|
||||
screen: Auction,
|
||||
navigationOptions: ({navigation}) => ({
|
||||
header: null,
|
||||
}),
|
||||
},
|
||||
Item: {
|
||||
screen: Item,
|
||||
navigationOptions: ({navigation}) => ({
|
||||
header: null,
|
||||
tabBarVisible: false,
|
||||
gesturesEnabled: false
|
||||
}),
|
||||
},
|
||||
ImageDetail: {
|
||||
screen: ImageDetail,
|
||||
navigationOptions: ({navigation}) => ({
|
||||
header: null,
|
||||
tabBarVisible: false,
|
||||
gesturesEnabled: false
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
export const BazaarStack = createStackNavigator({
|
||||
Bazaar: {
|
||||
screen: Marketplace,
|
||||
navigationOptions: ({navigation}) => ({
|
||||
header: null,
|
||||
}),
|
||||
},
|
||||
Item: {
|
||||
screen: Item,
|
||||
navigationOptions: ({navigation}) => ({
|
||||
header: null,
|
||||
tabBarVisible: false,
|
||||
gesturesEnabled: false
|
||||
}),
|
||||
},
|
||||
ImageDetail: {
|
||||
screen: ImageDetail,
|
||||
navigationOptions: ({navigation}) => ({
|
||||
header: null,
|
||||
tabBarVisible: false,
|
||||
gesturesEnabled: false
|
||||
}),
|
||||
},
|
||||
Checkout: {
|
||||
screen: Checkout,
|
||||
navigationOptions: ({navigation}) => ({
|
||||
header: null,
|
||||
tabBarVisible: false,
|
||||
gesturesEnabled: false
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
export const EventsStack = createStackNavigator({
|
||||
Events: {
|
||||
screen: Events,
|
||||
navigationOptions: ({ navigation }) => ({
|
||||
header: null,
|
||||
tabBarVisible: false,
|
||||
gesturesEnabled: false
|
||||
}),
|
||||
}
|
||||
});
|
||||
|
||||
export const createRootNavigator = () => {
|
||||
return StackNavigator(
|
||||
{
|
||||
AuctionStack: {
|
||||
screen: AuctionStack,
|
||||
navigationOptions: {
|
||||
gesturesEnabled: false
|
||||
}
|
||||
},
|
||||
BazaarStack: {
|
||||
screen: BazaarStack,
|
||||
navigationOptions: {
|
||||
gesturesEnabled: false
|
||||
}
|
||||
},
|
||||
Tabs: {
|
||||
screen: Tabs,
|
||||
navigationOptions: {
|
||||
gesturesEnabled: false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
headerMode: "none",
|
||||
mode: "modal"
|
||||
}
|
||||
);
|
||||
};
|
||||
92
app/screens/Auction.js
Normal file
92
app/screens/Auction.js
Normal file
@@ -0,0 +1,92 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import {
|
||||
FlatList,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} from 'react-native';
|
||||
|
||||
import { SORT_MODES, VIEW_MODES } from '../constants/constants.js';
|
||||
|
||||
import GridItem from '../components/Item/Grid.js';
|
||||
import ListItem from '../components/Item/List.js';
|
||||
|
||||
export default class Auction extends Component {
|
||||
static get propTypes() {
|
||||
return {
|
||||
changeFilter: PropTypes.func,
|
||||
items: PropTypes.array.isRequired,
|
||||
};
|
||||
}
|
||||
|
||||
static get defaultProps() {
|
||||
return {
|
||||
changeFilter: () => { console.log('Change Filter Default Prop', arguments); },
|
||||
header: null,
|
||||
};
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.changeFilter = this.changeFilter.bind(this);
|
||||
this.changeViewMode = this.changeViewMode.bind(this);
|
||||
|
||||
this.state = {
|
||||
sort: SORT_MODES.TITLE_ASC,
|
||||
view: VIEW_MODES.LIST,
|
||||
};
|
||||
}
|
||||
|
||||
changeFilter(filter) {
|
||||
this.props.changeFilter('auction', filter);
|
||||
}
|
||||
|
||||
changeViewMode(mode) {
|
||||
this.setState({ view: mode });
|
||||
}
|
||||
|
||||
_keyExtractor = (item, index) => item.id;
|
||||
|
||||
_renderItem = (view) => ({ item }) => {
|
||||
if (view === VIEW_MODES.GRID) {
|
||||
return <GridItem details={item} />;
|
||||
}
|
||||
|
||||
return <ListItem details={item} />;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { items, view } = this.state;
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<FilterBar
|
||||
changeFilterer={this.changeFilter}
|
||||
changeViewMode={this.changeViewMode}
|
||||
/>
|
||||
<FlatList
|
||||
data={items}
|
||||
keyExtractor={this._keyExtractor}
|
||||
renderItem={this.renderItem(view)}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#F5FCFF',
|
||||
},
|
||||
title: {
|
||||
fontSize: 20,
|
||||
textAlign: 'center',
|
||||
margin: 10,
|
||||
}
|
||||
});
|
||||
32
app/screens/Checkout.js
Normal file
32
app/screens/Checkout.js
Normal file
@@ -0,0 +1,32 @@
|
||||
import React, { Component } from 'react';
|
||||
import {
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} from 'react-native';
|
||||
|
||||
export default class Checkout extends Component {
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.title}>
|
||||
Checkout
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#F5FCFF',
|
||||
},
|
||||
title: {
|
||||
fontSize: 20,
|
||||
textAlign: 'center',
|
||||
margin: 10,
|
||||
}
|
||||
});
|
||||
124
app/screens/Event.js
Normal file
124
app/screens/Event.js
Normal file
@@ -0,0 +1,124 @@
|
||||
import React, { Component } from 'react';
|
||||
import {
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} from 'react-native';
|
||||
|
||||
export default class Event extends Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
event,
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.title}>
|
||||
Event
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#F5FCFF',
|
||||
},
|
||||
title: {
|
||||
fontSize: 20,
|
||||
textAlign: 'center',
|
||||
margin: 10,
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
const event = {
|
||||
isTicketed: true,
|
||||
requireLoginToSeeAuction: false,
|
||||
_id: "5d1f0a9289511160ddd681f4",
|
||||
description: "Cumque rerum nihil sit libero in.. Excepturi molestiae dicta.. Ratione perspiciatis similique et sed corrupti excepturi ut consequatur in.. Impedit voluptate deleniti suscipit vero tenetur.. Aut ut saepe nesciunt voluptas quod nam laudantium unde.",
|
||||
endTime: "2020-01-02T05:39:39.957Z",
|
||||
images: [
|
||||
{
|
||||
_id: "5d1f0a9289511160ddd681f7",
|
||||
url: "https://lorempixel.com/640/480/cats?37458"
|
||||
},
|
||||
{
|
||||
_id: "5d1f0a9289511160ddd681f6",
|
||||
url: "https://lorempixel.com/640/480/cats?80772"
|
||||
},
|
||||
{
|
||||
_id: "5d1f0a9289511160ddd681f5",
|
||||
url: "https://lorempixel.com/640/480/cats?2451"
|
||||
}
|
||||
],
|
||||
posts: [
|
||||
{
|
||||
isPublic: true,
|
||||
scheduledPost: false,
|
||||
_id: "5d1f0a9289511160ddd681fb",
|
||||
author: "Dandre Leuschke",
|
||||
title: "Facere a atque.",
|
||||
content: "Reprehenderit minus ut. Quibusdam reiciendis rerum fugit est quis. Omnis architecto magni. Libero et nihil excepturi facere doloribus doloremque in error deleniti. Modi et id sint exercitationem esse tenetur iure. Occaecati aliquid maxime ratione asperiores repudiandae.\n \rQuia ipsam quia fuga pariatur odit sunt. Sed dicta earum officiis quo quo. Sunt maiores itaque ipsum eum. Quia repudiandae et. Asperiores et est. Et modi minus cupiditate voluptas quia maxime delectus voluptatum.\n \rDignissimos numquam non nulla aut ea a quis. Et consequuntur porro ut dolorem iure est voluptas. Autem ullam mollitia perferendis mollitia sequi voluptatem numquam voluptatum.\n \rIllum magnam consequatur iste ut libero tenetur aut eos quibusdam. Aut molestiae ullam maiores. Sapiente est sed.",
|
||||
sendNotification: null,
|
||||
timestamp: "2019-06-26T01:41:43.197Z"
|
||||
},
|
||||
{
|
||||
isPublic: false,
|
||||
scheduledPost: false,
|
||||
_id: "5d1f0a9289511160ddd681fa",
|
||||
author: "Kari Ullrich",
|
||||
title: "Iure ea est.",
|
||||
content: "Molestiae magni nisi. Sit est sed aliquid corrupti perferendis natus. Est dolore totam. Quis excepturi id id ipsa. Accusantium aliquam facere laboriosam quo mollitia voluptatum.\n \rEum nulla ratione. Quia fuga ipsum fuga est temporibus eligendi aut. Aperiam alias architecto molestias aut beatae ullam harum. Magni in numquam dolores.\n \rIpsum quod itaque vero iste. Architecto vero ut quia. Voluptas modi provident et consequatur consequatur ex quia.",
|
||||
sendNotification: null,
|
||||
timestamp: "2019-06-22T19:29:40.080Z"
|
||||
},
|
||||
{
|
||||
isPublic: false,
|
||||
scheduledPost: true,
|
||||
_id: "5d1f0a9289511160ddd681f9",
|
||||
author: "Maida Bednar",
|
||||
title: "Et dignissimos rem officiis non voluptas ea totam atque.",
|
||||
content: "Totam dolorum quia dolor. Tempore molestiae error eos qui rerum ipsa nihil voluptas est. Aut et adipisci voluptatibus. Consectetur vel sit est voluptatum fuga qui minima sit recusandae.\n \rProvident dolorem ut. In rerum hic porro odio illo praesentium qui quis animi. Cupiditate est tenetur magnam commodi. Id est temporibus itaque corporis voluptatum omnis repellat eius. Deserunt tempora cum facilis. Nesciunt blanditiis voluptas mollitia.\n \rVoluptate vero omnis non nesciunt officia. Ipsa perferendis soluta. Sed unde labore autem quae amet deleniti consequatur. Molestias ducimus iusto a ipsa. Repellat vero accusamus impedit quo. Molestias nam inventore aut quaerat error odio eius enim velit.",
|
||||
sendNotification: "2019-08-16T20:54:01.358Z",
|
||||
timestamp: "2019-06-27T23:24:40.677Z"
|
||||
},
|
||||
{
|
||||
isPublic: true,
|
||||
scheduledPost: false,
|
||||
_id: "5d1f0a9289511160ddd681f8",
|
||||
author: "Emory Ortiz II",
|
||||
title: "Ut doloribus quas impedit velit nostrum nemo facere nam.",
|
||||
content: "Et et ab sapiente voluptatibus. Modi aperiam ad mollitia sunt minima architecto. Soluta aliquid vero. Est non eum esse. Numquam rerum quod. Itaque quasi numquam dolor impedit ut sit.\n \rQuo sapiente optio ea labore non dolor. Et nemo recusandae ea. Laboriosam magnam commodi excepturi quis soluta et. Molestias pariatur et ullam nesciunt ullam.\n \rCulpa enim vitae modi non totam sit eius beatae. Quia autem atque veniam et at neque. Reprehenderit possimus esse a qui nobis et laborum rerum.\n \rEt odio totam adipisci autem. Qui at quo aliquid ut rerum. Iste enim voluptatibus ipsam distinctio doloribus laborum neque. Qui quia quis sint repellendus.",
|
||||
sendNotification: null,
|
||||
timestamp: "2019-07-02T22:27:11.838Z"
|
||||
}
|
||||
],
|
||||
showFrom: "2019-06-12T12:56:23.090Z",
|
||||
showUntil: "2020-01-02T05:39:39.000Z",
|
||||
startTime: "2019-06-26T12:56:23.090Z",
|
||||
tagline: "Voluptates reiciendis eos tempora placeat dolores eum omnis voluptatibus molestiae.",
|
||||
title: "et",
|
||||
url: "https://www.mfa.org/summer-party",
|
||||
ticketClasses: [
|
||||
{
|
||||
price: 171,
|
||||
_id: "5d1f0a9289511160ddd68225",
|
||||
available: 105,
|
||||
capacity: 226,
|
||||
endSale: "2020-01-02T05:39:39.957Z",
|
||||
itemId: "5d1f0a9289511160ddd681fc",
|
||||
name: "Magni vero voluptatem velit occaecati in fugit et dolor quas.",
|
||||
startSale: "2019-06-26T12:56:23.090Z"
|
||||
}
|
||||
],
|
||||
};
|
||||
32
app/screens/Events.js
Normal file
32
app/screens/Events.js
Normal file
@@ -0,0 +1,32 @@
|
||||
import React, { Component } from 'react';
|
||||
import {
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} from 'react-native';
|
||||
|
||||
export default class Events extends Component {
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.title}>
|
||||
Events
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#F5FCFF',
|
||||
},
|
||||
title: {
|
||||
fontSize: 20,
|
||||
textAlign: 'center',
|
||||
margin: 10,
|
||||
}
|
||||
});
|
||||
32
app/screens/ImageDetail.js
Normal file
32
app/screens/ImageDetail.js
Normal file
@@ -0,0 +1,32 @@
|
||||
import React, { Component } from 'react';
|
||||
import {
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} from 'react-native';
|
||||
|
||||
export default class ImageDetail extends Component {
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.title}>
|
||||
Item
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#F5FCFF',
|
||||
},
|
||||
title: {
|
||||
fontSize: 20,
|
||||
textAlign: 'center',
|
||||
margin: 10,
|
||||
}
|
||||
});
|
||||
32
app/screens/Item.js
Normal file
32
app/screens/Item.js
Normal file
@@ -0,0 +1,32 @@
|
||||
import React, { Component } from 'react';
|
||||
import {
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} from 'react-native';
|
||||
|
||||
export default class Item extends Component {
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.title}>
|
||||
Item
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#F5FCFF',
|
||||
},
|
||||
title: {
|
||||
fontSize: 20,
|
||||
textAlign: 'center',
|
||||
margin: 10,
|
||||
}
|
||||
});
|
||||
32
app/screens/Login.js
Normal file
32
app/screens/Login.js
Normal file
@@ -0,0 +1,32 @@
|
||||
import React, { Component } from 'react';
|
||||
import {
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} from 'react-native';
|
||||
|
||||
export default class Login extends Component {
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.title}>
|
||||
Login
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#F5FCFF',
|
||||
},
|
||||
title: {
|
||||
fontSize: 20,
|
||||
textAlign: 'center',
|
||||
margin: 10,
|
||||
}
|
||||
});
|
||||
92
app/screens/Marketplace.js
Normal file
92
app/screens/Marketplace.js
Normal file
@@ -0,0 +1,92 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import {
|
||||
FlatList,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} from 'react-native';
|
||||
|
||||
import { SORT_MODES, VIEW_MODES } from '../constants/constants.js';
|
||||
|
||||
import GridItem from '../components/Item/Grid.js';
|
||||
import ListItem from '../components/Item/List.js';
|
||||
|
||||
export default class Marketplace extends Component {
|
||||
static get propTypes() {
|
||||
return {
|
||||
changeFilter: PropTypes.func,
|
||||
items: PropTypes.array.isRequired,
|
||||
};
|
||||
}
|
||||
|
||||
static get defaultProps() {
|
||||
return {
|
||||
changeFilter: () => { console.log('Change Filter Default Prop', arguments); },
|
||||
header: null,
|
||||
};
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.changeFilter = this.changeFilter.bind(this);
|
||||
this.changeViewMode = this.changeViewMode.bind(this);
|
||||
|
||||
this.state = {
|
||||
sort: SORT_MODES.TITLE_ASC,
|
||||
view: VIEW_MODES.LIST,
|
||||
};
|
||||
}
|
||||
|
||||
changeFilter(filter) {
|
||||
this.props.changeFilter('market', filter);
|
||||
}
|
||||
|
||||
changeViewMode(mode) {
|
||||
this.setState({ view: mode });
|
||||
}
|
||||
|
||||
_keyExtractor = (item, index) => item.id;
|
||||
|
||||
_renderItem = (view) => ({ item }) => {
|
||||
if (view === VIEW_MODES.GRID) {
|
||||
return <GridItem {...item} />;
|
||||
}
|
||||
|
||||
return <ListItem {...item} />;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { items, view } = this.state;
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<FilterBar
|
||||
changeFilterer={this.changeFilter}
|
||||
changeViewMode={this.changeViewMode}
|
||||
/>
|
||||
<FlatList
|
||||
data={items}
|
||||
keyExtractor={this._keyExtractor}
|
||||
renderItem={this.renderItem(view)}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#F5FCFF',
|
||||
},
|
||||
title: {
|
||||
fontSize: 20,
|
||||
textAlign: 'center',
|
||||
margin: 10,
|
||||
}
|
||||
});
|
||||
32
app/screens/Profile.js
Normal file
32
app/screens/Profile.js
Normal file
@@ -0,0 +1,32 @@
|
||||
import React, { Component } from 'react';
|
||||
import {
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} from 'react-native';
|
||||
|
||||
export default class Profile extends Component {
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.title}>
|
||||
Profile
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#F5FCFF',
|
||||
},
|
||||
title: {
|
||||
fontSize: 20,
|
||||
textAlign: 'center',
|
||||
margin: 10,
|
||||
}
|
||||
});
|
||||
33
app/screens/Ticketing.js
Normal file
33
app/screens/Ticketing.js
Normal file
@@ -0,0 +1,33 @@
|
||||
import React, { Component } from 'react';
|
||||
import {
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} from 'react-native';
|
||||
|
||||
export default class Ticketing extends Component {
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.title}>
|
||||
Ticketing
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#F5FCFF',
|
||||
},
|
||||
title: {
|
||||
fontSize: 20,
|
||||
textAlign: 'center',
|
||||
margin: 10,
|
||||
}
|
||||
});
|
||||
|
||||
9
app/store/index.js
Normal file
9
app/store/index.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import { applyMiddleware, compose, createStore } from 'redux';
|
||||
import thunk from 'redux-thunk';
|
||||
|
||||
import rootReducer from '../reducers/index.js';
|
||||
|
||||
export const store = createStore(
|
||||
rootReducer,
|
||||
compose(applyMiddleware(thunk)),
|
||||
);
|
||||
Reference in New Issue
Block a user