unknown quantity UI

This commit is contained in:
Bart Akeley 2020-04-26 12:27:24 -05:00
parent 96e24881fc
commit b958515311
10 changed files with 92 additions and 61 deletions

View file

@ -18,7 +18,8 @@
"__DEV__": true "__DEV__": true
}, },
"rules": { "rules": {
"react/display-name": 1 "react/display-name": 1,
"react/prop-types": 0
}, },
"settings": { "settings": {
"react": { "react": {

View file

@ -20,6 +20,15 @@
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="wheresthetp.auth0.com"
android:pathPrefix="/android/${applicationId}/callback"
android:scheme="${applicationId}" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" /> <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />

View file

@ -2,7 +2,6 @@ import React from 'react';
import { View } from 'react-native'; import { View } from 'react-native';
import { pure } from 'recompose'; import { pure } from 'recompose';
import ProductRecord from '../records/ProductRecord'; import ProductRecord from '../records/ProductRecord';
import typeof PlaceRecord from '../records/PlaceRecord';
import theme from '../ui-theme'; import theme from '../ui-theme';
import { Link } from 'react-router-native'; import { Link } from 'react-router-native';
import { routeWithTitle } from '../helpers/RouteHelpers'; import { routeWithTitle } from '../helpers/RouteHelpers';

View file

@ -1,23 +1,12 @@
// @flow import React from 'react';
import React, { Component } from 'react'; import { View, FlatList } from 'react-native';
import { View } from 'react-native';
import { type SetSeq } from 'immutable'; import { type SetSeq } from 'immutable';
import ProductRecord from '../records/ProductRecord'; import ProductRecord from '../records/ProductRecord';
import { compose, pure } from 'recompose'; import { compose, pure } from 'recompose';
import { pipe } from 'ramda'; import { pipe } from 'ramda';
import { withFilter } from '../enhancers/filterEnhancers'; import { withFilter } from '../enhancers/filterEnhancers';
import FilterRecord from '../records/FilterRecord';
import { compareQuantity } from '../helpers/QuantityHelpers'; import { compareQuantity } from '../helpers/QuantityHelpers';
// promote this somewhere?
type homomorph<T> = T => T;
type Props = {
filter: FilterRecord,
productsSeq: SetSeq<ProductRecord>,
children: (product: ProductRecord) => Component<*, *, *>,
};
const sortByDistance = (productsSeq: SetSeq<ProductRecord>): SetSeq<ProductRecord> => { const sortByDistance = (productsSeq: SetSeq<ProductRecord>): SetSeq<ProductRecord> => {
return productsSeq.sort((left, right) => left.distance - right.distance); return productsSeq.sort((left, right) => left.distance - right.distance);
}; };
@ -33,7 +22,7 @@ const sortByQuantity = (productsSeq: SetSeq<ProductRecord>): SetSeq<ProductRecor
}); });
}; };
const getSortBy = (filter: FilterRecord): homomorph<*> => { const getSortBy = filter => {
switch (filter.orderby) { switch (filter.orderby) {
case 'quantity': case 'quantity':
return sortByQuantity; return sortByQuantity;
@ -47,7 +36,7 @@ const getSortBy = (filter: FilterRecord): homomorph<*> => {
const intoArray = (productsSeq: SetSeq<ProductRecord>): Array<ProductRecord> => const intoArray = (productsSeq: SetSeq<ProductRecord>): Array<ProductRecord> =>
productsSeq ? productsSeq.toArray() : []; productsSeq ? productsSeq.toArray() : [];
const ProductList = (props: Props) => { const ProductList = props => {
const { filter, productsSeq, children } = props; const { filter, productsSeq, children } = props;
if (!productsSeq) { if (!productsSeq) {
@ -59,7 +48,15 @@ const ProductList = (props: Props) => {
intoArray intoArray
)(productsSeq); )(productsSeq);
return <View style={{ flexShrink: 2 }}>{items.map(children)}</View>; return (
<View style={{ flexShrink: 2 }}>
<FlatList
data={items}
renderItem={({ item }) => children(item)}
keyExtractor={item => item.id}
/>
</View>
);
}; };
export default compose( export default compose(

View file

@ -0,0 +1,47 @@
import React from 'react';
import { View, Text, Button } from 'react-native';
import RouterButton from 'react-router-native-button';
import { SubText } from './ItemTile';
import { getQuantityLabelText } from '../helpers/QuantityHelpers';
import { loginWithBackto } from '../helpers/RouteHelpers';
import moment from 'moment';
import theme from '../ui-theme';
const QuantityPanel = ({ style, isAuthed, product, onUpdatePress }) => (
<View
style={{
...style,
flexBasis: 50,
flexGrow: 1,
flexDirection: 'column',
justifyContent: 'space-between',
}}>
{product.quantity ? (
<>
<Text style={{ fontSize: 42, color: 'black' }}>
{getQuantityLabelText(product.quantity)}
</Text>
<SubText>
Last updated at {moment(product.lastupdated).format('h:mm A on MMM D, YYYY')}
</SubText>
</>
) : (
<Text style={{ fontSize: 24, color: 'black', flex: 1, flexWrap: 'wrap' }}>
Be the first to update the amount of this product.
</Text>
)}
{isAuthed && (
<Button title="Update amount" onPress={onUpdatePress} color={theme.palette.primaryColor} />
)}
{!isAuthed && (
<RouterButton
title="Update Amount"
to={loginWithBackto(`/product/${product.id}?loginAction=open-quantity-modal`)}
color={theme.actionButton.speedDialActionIcon.backgroundColor}
style={{ fontSize: 20, fontWeight: 500 }}
/>
)}
</View>
);
export default QuantityPanel;

View file

@ -11,4 +11,4 @@ export const BASE_URL = '192.168.1.247:3000';
export const GoogleAPIKey = 'AIzaSyBfMm1y6JayCbXrQmgAG1R3ka4ZOJno_5E'; export const GoogleAPIKey = 'AIzaSyBfMm1y6JayCbXrQmgAG1R3ka4ZOJno_5E';
export const auth0ClientId = 'y3jfovcuWnEhdisNaA666rxsf4hyZrUa'; export const auth0ClientId = '4p1BPIX4L6iwTv5gl3ZpHpU4Ye5YatQ3';

View file

@ -9,7 +9,7 @@ import { Divider, Icon } from 'react-native-material-ui';
import { getBackTo } from '../helpers/RouteHelpers'; import { getBackTo } from '../helpers/RouteHelpers';
import ResetPasswordButton from '../components/ResetPasswordButton'; import ResetPasswordButton from '../components/ResetPasswordButton';
const auth0ErrToStr = (message) => { const auth0ErrToStr = message => {
if (typeof message === 'string') { if (typeof message === 'string') {
return message; return message;
} }
@ -24,9 +24,9 @@ type Props = {
error: string, error: string,
setError: (err: string) => void, setError: (err: string) => void,
email: string, email: string,
setEmail: (string) => void, setEmail: string => void,
password: string, password: string,
setPassword: (string) => void, setPassword: string => void,
router: { router: {
route: { route: {
location: { location: {
@ -43,7 +43,7 @@ type Props = {
deauthUser: () => void, deauthUser: () => void,
createUser: () => void, createUser: () => void,
isNewUser: boolean, isNewUser: boolean,
setIsNewUser: (boolean) => void, setIsNewUser: boolean => void,
resetPassword: () => void, resetPassword: () => void,
}; };
@ -83,7 +83,9 @@ const LoginPageComponent = ({
</Text> </Text>
)} )}
<Text style={{ fontSize: 36, fontWeight: '700', marginTop: 32, marginBottom: 16 }}>Sign In</Text> <Text style={{ fontSize: 36, fontWeight: '700', marginTop: 32, marginBottom: 16 }}>
Sign In
</Text>
<View style={{ flexDirection: 'row', padding: 16, paddingBottom: 0 }}> <View style={{ flexDirection: 'row', padding: 16, paddingBottom: 0 }}>
<View style={{ flex: 1, flexDirection: 'column' }}> <View style={{ flex: 1, flexDirection: 'column' }}>
@ -160,7 +162,7 @@ export default compose(
withState('password', 'setPassword', ''), withState('password', 'setPassword', ''),
withState('isNewUser', 'setIsNewUser', false), withState('isNewUser', 'setIsNewUser', false),
withHandlers({ withHandlers({
checkAuth: (props) => async () => { checkAuth: props => async () => {
const isLoggedIn = await AuthManager.checkIsAuthed(); const isLoggedIn = await AuthManager.checkIsAuthed();
if (isLoggedIn) { if (isLoggedIn) {
const backTo = getBackTo(props); const backTo = getBackTo(props);
@ -175,6 +177,8 @@ export default compose(
await AuthManager.authenticate({ email, password }); await AuthManager.authenticate({ email, password });
checkAuth(); checkAuth();
} catch (err) { } catch (err) {
console.log(err);
debugger;
setError('You have entered an invalid email or password. Please try again.'); setError('You have entered an invalid email or password. Please try again.');
} }
}, },

View file

@ -1,6 +1,5 @@
// @flow
import React from 'react'; import React from 'react';
import { Button, Image, Text, View } from 'react-native'; import { Image, View } from 'react-native';
import theme from '../ui-theme'; import theme from '../ui-theme';
import { StrongText, SubText } from '../components/ItemTile'; import { StrongText, SubText } from '../components/ItemTile';
import typeof ProductRecord from '../records/ProductRecord'; import typeof ProductRecord from '../records/ProductRecord';
@ -21,10 +20,7 @@ import Carousel from 'react-native-looped-carousel';
import CountBadge from '../components/CountBadge'; import CountBadge from '../components/CountBadge';
import { routeWithTitle, loginWithBackto } from '../helpers/RouteHelpers'; import { routeWithTitle, loginWithBackto } from '../helpers/RouteHelpers';
import { Link } from 'react-router-native'; import { Link } from 'react-router-native';
import moment from 'moment';
import { withUpdateQuantity } from '../enhancers/quantityEnhancers'; import { withUpdateQuantity } from '../enhancers/quantityEnhancers';
import { getQuantityLabelText } from '../helpers/QuantityHelpers';
import RouterButton from 'react-router-native-button';
import QuantityModal from '../modals/QuantityModal'; import QuantityModal from '../modals/QuantityModal';
import { identity, pathOr } from 'ramda'; import { identity, pathOr } from 'ramda';
import Spinner from 'react-native-loading-spinner-overlay'; import Spinner from 'react-native-loading-spinner-overlay';
@ -35,6 +31,7 @@ import { withAuthed } from '../enhancers/authEnhancers';
import { withFaves } from '../enhancers/favesEnhancer'; import { withFaves } from '../enhancers/favesEnhancer';
import debounce from '../helpers/debounce'; import debounce from '../helpers/debounce';
import { withCurrentPath, withReplaceRoute } from '../enhancers/routeEnhancers'; import { withCurrentPath, withReplaceRoute } from '../enhancers/routeEnhancers';
import QuantityTile from '../components/QuantityTile';
const { productDetails: style } = theme; const { productDetails: style } = theme;
@ -144,35 +141,12 @@ export const ProductDetail = (props: Props) => {
</View> </View>
</Link> </Link>
</View> </View>
<View <QuantityTile
style={{ product={product}
flexBasis: 100, isAuthed={isAuthed}
flexGrow: 1, onUpdatePress={toggleQuantityModal}
...contentTileStyle, style={contentTileStyle}
flexDirection: 'column', />
justifyContent: 'space-between',
}}>
<Text style={{ fontSize: 42, color: 'black' }}>
{getQuantityLabelText(product.quantity)}
</Text>
<SubText>
Last updated at {moment(product.lastupdated).format('h:mm A on MMM D, YYYY')}
</SubText>
{isAuthed && (
<Button
title="Update quantity"
onPress={toggleQuantityModal}
color={theme.palette.primaryColor}
/>
)}
{!isAuthed && (
<RouterButton
title="Log in to update quantity"
to={loginWithBackto(`/product/${product.id}?loginAction=open-quantity-modal`)}
color={theme.actionButton.speedDialActionIcon.backgroundColor}
/>
)}
</View>
<View style={{ flex: 1, ...contentTileStyle }}> <View style={{ flex: 1, ...contentTileStyle }}>
{isAuthed && isFave ? ( {isAuthed && isFave ? (
<IconButton <IconButton

View file

@ -28,7 +28,7 @@ const ProductList = props => {
style={{ flex: 1 }} style={{ flex: 1 }}
refreshControl={<RefreshControl refreshing={refreshing} onRefresh={onPulldown} />}> refreshControl={<RefreshControl refreshing={refreshing} onRefresh={onPulldown} />}>
<ProductsList productsSeq={productsSeq}> <ProductsList productsSeq={productsSeq}>
{product => <ProductTile key={product.id} product={product} />} {product => <ProductTile product={product} />}
</ProductsList> </ProductsList>
</ScrollView> </ScrollView>
)} )}

View file

@ -86,7 +86,7 @@ export default {
fontSize: 25, fontSize: 25,
color: COLOR.black, color: COLOR.black,
}, },
pressHighlightColor: COLOR.pink500, pressHighlightColor: primaryColor,
}, },
countBadge: { countBadge: {
backgroundColor: '#00506C', backgroundColor: '#00506C',