Optimizations / editing works

better styling
This commit is contained in:
2021-03-18 23:17:25 +01:00
parent 3afe7cb5d4
commit ef5095dd74
9 changed files with 205 additions and 128 deletions

View File

@@ -1,5 +1,5 @@
import React, { useRef, useEffect, useState, Suspense } from 'react';
import { StyleSheet, Text, TouchableOpacity, View, Animated } from 'react-native';
import React, { useRef, useEffect, useState } from 'react';
import { StyleSheet, Text, TouchableOpacity, View, Animated, Image } from 'react-native';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
//themes
import { COLORS } from '../../themes/Colors';
@@ -19,7 +19,7 @@ const ListedItem = (props) => {
if (!product) {
product = {
productName: props.id,
tag: 'uncathegorized',
tag: 'uncategorized',
}
}
const tag = useSelector(state => state.tags.find((tag) => tag.tagName === product.tag))
@@ -95,7 +95,6 @@ const ListedItem = (props) => {
return (
<Suspense fallback={<Text>Loading</Text>}>
<View style={{ flex: 1, paddingLeft: 8, paddingRight: 8, flexDirection: 'row', alignItems: 'flex-start', justifyContent: 'space-between' }}>
<Animated.View style={[styles.listedItemStyle, { backgroundColor: tag.color + '33' }, item.checked ? styles.listedItemChecked : {}, {
transform: [{
@@ -106,6 +105,9 @@ const ListedItem = (props) => {
}
]
}]} >
<Image source={{ uri: product.image ? product.image : 'https://icons-for-free.com/iconfiles/png/512/linecon+products+round+icon-1320165923260225670.png' }}
style={styles.image} />
<TouchableOpacity style={{ flex: 1, }}
onPress={() => dispatch(modalToggle(props.id))}
onLongPress={() => dispatchAnim()}>
@@ -146,7 +148,6 @@ const ListedItem = (props) => {
</Animated.View>
</TouchableOpacity>
</View>
</Suspense>
);
}
export default React.memo(ListedItem);
@@ -165,6 +166,18 @@ const styles = StyleSheet.create({
listedItemChecked: {
backgroundColor: '#253f34',
},
image: {
position: 'absolute',
right: 0,
top: 0,
bottom: 0,
opacity: 0.06,
width: 200,
borderTopLeftRadius: 150,
borderBottomLeftRadius: 150,
},
textItem: {
width: '80%',
flex: 1,

View File

@@ -158,8 +158,6 @@ const styles = StyleSheet.create({
},
listedItemButton: {
flex: 1,
padding: 2,
paddingBottom: 3,
alignItems: 'flex-start',
flexDirection: 'row',
},
@@ -181,11 +179,18 @@ const styles = StyleSheet.create({
color: COLORS.textW1,
},
textPrice: {
left: 8,
fontFamily: 'Roboto',
fontSize: height * 0.5,
color: COLORS.textW1,
backgroundColor: '#000' + '3',
minWidth: 50,
maxWidth: '70%',
borderBottomLeftRadius: height / 2,
borderRadius: height / 3,
marginBottom: 3,
marginLeft: 3,
paddingLeft: 5,
paddingRight: 10,
fontFamily: 'Roboto',
fontSize: height * 0.55,
},
image: {
position: 'absolute',

View File

@@ -61,12 +61,11 @@ export default AddItemModal = () => {
setDetails('');
setFocussed(false)
setProductsList(products.map((product) => product.productName));
}
else {
alert('You should give both a product and an amount');
}
dispatch(toggleVisibility('addItemModalVisible'));
}
else {
alert('You should insert both a product name and an amount');
}
};
const closeModal = () => {
setFocussed(false)
@@ -91,7 +90,7 @@ export default AddItemModal = () => {
<Text style={styles.modalHeaderText}>Add item</Text>
<View style={styles.inputRow}>
<MaterialCommunityIcons name="food" color={COLORS.textW0 + '55'} size={30} />
<MaterialCommunityIcons name="food" color={COLORS.textW0 + '55'} size={25} />
<TextInput
placeholder={'Product name'}
placeholderTextColor={'grey'}
@@ -113,7 +112,7 @@ export default AddItemModal = () => {
</ScrollView>
</View>
<View style={styles.inputRow}>
<MaterialCommunityIcons name="label-percent-outline" color={COLORS.textW0 + '55'} size={30} />
<MaterialCommunityIcons name="label-percent-outline" color={COLORS.textW0 + '55'} size={25} />
<TextInput
placeholder={'Amount'}
placeholderTextColor={'grey'}
@@ -125,7 +124,7 @@ export default AddItemModal = () => {
{amount ? <MaterialCommunityIcons style = {{right:15}}name="check" color={COLORS.primary} size={25} /> : <MaterialCommunityIcons style = {{right:10, bottom: 10,}}name="asterisk" color={COLORS.actionCancel + 'aa'} size={12} />}
</View>
<View style={styles.inputRow}>
<MaterialCommunityIcons name="account-supervisor-circle" color={COLORS.textW0 + '55'} size={30} />
<MaterialCommunityIcons name="account-supervisor-circle" color={COLORS.textW0 + '55'} size={25} />
<TextInput
placeholder={'For'}
placeholderTextColor={'grey'}
@@ -136,7 +135,7 @@ export default AddItemModal = () => {
{person ? <MaterialCommunityIcons style = {{right:15}}name="check" color={COLORS.primary} size={25} /> : <View/>}
</View>
<View style={styles.inputRow}>
<MaterialCommunityIcons name="folder-information-outline" color={COLORS.textW0 + '55'} size={30} />
<MaterialCommunityIcons name="pencil-plus-outline" color={COLORS.textW0 + '55'} size={25} />
<TextInput
placeholder={'Additional details'}
placeholderTextColor={'grey'}

View File

@@ -10,7 +10,7 @@ import { COLORS } from '../../../themes/Colors';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
//redux
import { useDispatch, useSelector } from 'react-redux';
import { useDispatch, useSelector} from 'react-redux';
import { productAdded } from '../../../redux/slices/groceryList/productsSlice';
import { toggleVisibility } from '../../../redux/slices/groceryList/toggleSlice';
@@ -22,7 +22,7 @@ export default AddProductModal = () => {
const [product, setProduct] = useState('');
const [tag, setTag] = useState('');
const [price, setPrice] = useState('');
const [image, setImage] = useState('https://icons-for-free.com/iconfiles/png/512/linecon+products+round+icon-1320165923260225670.png');
const [image, setImage] = useState('');
//tags
const tags = useSelector(state => state.tags)
@@ -47,29 +47,26 @@ export default AddProductModal = () => {
};
//tags
const toggleModal = () => {
if (modalVisible) {
if (product !== '' && tags.find((listTag) => listTag.tagName === tag)) {
if (modalVisible && product !== '' && tags.find((listTag) => listTag.tagName === tag)) {
dispatch(productAdded(product, tag, price, image));
}
else {
alert('You should give both a product name and a useable tag');
}
}
setTagsList(tags.map((listTag) => listTag.tagName));
dispatch(toggleVisibility('addProductModalVisible'));
setProduct('');
setTag('');
setPrice();
setFocussed(false)
setImage('https://icons-for-free.com/iconfiles/png/512/linecon+products+round+icon-1320165923260225670.png');
};
setImage('');
}
else {
alert('You should give both a product name and a useable tag');
}
}
const closeModal = () => {
setTagsList(tags.map((listTag) => listTag.tagName));
setProduct('');
setTag();
setPrice();
setImage('https://icons-for-free.com/iconfiles/png/512/linecon+products+round+icon-1320165923260225670.png');
setImage('');
setFocussed(false)
dispatch(toggleVisibility('addProductModalVisible'));
@@ -83,7 +80,6 @@ export default AddProductModal = () => {
style={styles.modalAddProduct} >
<View style={{
borderRadius: 10,
padding: 5,
backgroundColor: COLORS.dp01,
}}>
<Text style={styles.modalHeaderText}>Add product</Text>
@@ -91,19 +87,23 @@ export default AddProductModal = () => {
<View style={{
flexDirection: 'row',
justifyContent: 'flex-start',
width: '100%',
}}>
<View style={{
width: '60%',
}}>
<View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'flex-start' }}>
<View style={styles.inputRow}>
<MaterialCommunityIcons name="food" color={COLORS.textW0 + '55'} size={25} />
<TextInput
placeholder={'Product name'}
placeholderTextColor={'grey'}
style={styles.textInput}
onChangeText={text => setProduct(text)}
/>
{product ? <MaterialCommunityIcons style={{ right: 15 }} name="check" color={COLORS.primary} size={25} /> : <MaterialCommunityIcons style={{ right: 10, bottom: 10, }} name="asterisk" color={COLORS.actionCancel + 'aa'} size={12} />}
</View>
<View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'flex-start' }}>
<View style={styles.inputRow}>
<MaterialCommunityIcons name="tag-text-outline" color={COLORS.textW0 + '55'} size={25} />
<TextInput
placeholder={'Tag'}
placeholderTextColor={'grey'}
@@ -113,6 +113,7 @@ export default AddProductModal = () => {
onFocus={() => setFocussed(true)}
onEndEditing={() => setFocussed(false)}
/>
{tag ? <MaterialCommunityIcons style={{ right: 15 }} name="check" color={COLORS.primary} size={25} /> : <MaterialCommunityIcons style={{ right: 10, bottom: 10, }} name="asterisk" color={COLORS.actionCancel + 'aa'} size={12} />}
<ScrollView style={styles.dropdown} keyboardShouldPersistTaps={'always'}>
{focussed ? tagsList.map((newTag, index) =>
<TouchableOpacity key={index} onPress={() => filterTagsList(newTag)} style={styles.dropdownProduct}>
@@ -121,33 +122,37 @@ export default AddProductModal = () => {
) : <View />}
</ScrollView>
</View>
<View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'flex-start' }}>
<Text style={styles.currencyPrefix}></Text>
<View style={styles.inputRow}>
<MaterialCommunityIcons name="currency-usd" color={COLORS.textW0 + '55'} size={25} />
<TextInput
placeholder={'Price'}
placeholderTextColor={'grey'}
style={[styles.textInput, { paddingLeft: 20 }]}
style={[styles.textInput]}
onChangeText={text => setPrice(text)}
keyboardType={'number-pad'}
/>
{price ? <MaterialCommunityIcons style={{ right: 15 }} name="check" color={COLORS.primary} size={25} /> : <View />}
</View>
<View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'flex-start' }}>
<View style={styles.inputRow}>
<MaterialCommunityIcons name="link-plus" color={COLORS.textW0 + '55'} size={25} />
<TextInput
placeholder={'Image url'}
placeholderTextColor={'grey'}
style={styles.textInput}
onChangeText={text => { if (text !== '') { return setImage(`https://www.googleapis.com/customsearch/v1?key=${product}&cx=017576662512468239146:omuauf_lfve&q=lectures`) } }}
onChangeText={text => setImage(text)}
/>
{image ? <MaterialCommunityIcons style={{ right: 15 }} name="check" color={COLORS.primary} size={25} /> : <View />}
</View>
</View>
<Image source={{ uri: image }}
style={{ width: 130, height: 130, marginTop: '5%', right: 10, borderRadius: 30, }} />
{image ? <Image source={{ uri: image }}
style={styles.image} />
: <View style={[styles.image,{borderColor: COLORS.dp00 +'88', borderWidth: 3,}]}/>}
</View>
<View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'space-evenly', marginTop: 20, marginBottom: 10, }}>
<TouchableOpacity title="Hide modal" style={styles.modalCloseButton} onPress={closeModal} >
<Text style={styles.modalCloseButtonText}>Cancel </Text>
<Text style={styles.modalCloseButtonText}> Cancel </Text>
</TouchableOpacity>
<View style={{
borderRadius: 10,
@@ -158,7 +163,7 @@ export default AddProductModal = () => {
}} />
<TouchableOpacity title="Hide modal" style={styles.modalAddButton} onPress={toggleModal} >
<Text style={styles.modalAddButtonText}>Add product</Text>
<Text style={styles.modalAddButtonText}> Add product </Text>
</TouchableOpacity>
</View>
</View>
@@ -183,6 +188,14 @@ const styles = StyleSheet.create({
fontSize: 18,
color: COLORS.textB0,
},
image: {
width: '40%',
height: '100%',
marginTop: '2%',
borderTopLeftRadius: 15,
borderBottomLeftRadius: 15,
},
modalAddButtonText: {
opacity: 0.8,
fontSize: 16,
@@ -195,37 +208,35 @@ const styles = StyleSheet.create({
color: COLORS.primary,
fontWeight: 'bold',
},
inputRow: {
flexDirection: 'row',
alignItems: 'flex-end',
justifyContent: 'flex-start',
width: '100%',
marginLeft: 5,
},
textInput: {
height: 25,
width: '80%',
left: 10,
borderBottomColor: COLORS.primary + 'aa',
borderBottomWidth: 1,
borderRadius: 3,
marginTop: 10,
padding: 0,
paddingLeft: 5,
paddingRight: 5,
paddingRight: 15,
color: COLORS.textW0,
fontSize: 18
},
currencyPrefix: {
position: 'absolute',
alignSelf: 'flex-end',
left: 15,
color: COLORS.primary + '99',
fontSize: 18,
},
dropdown: {
zIndex: 1,
position: 'absolute',
maxHeight: 100,
width: 150,
width: '100%',
top: 40,
left: 10,

View File

@@ -18,7 +18,7 @@ export default EditItemModal = (props) => {
if (!product) {
product = {
productName: props.id,
tag: 'uncathegorized',
tag: 'uncategorized',
}
}
@@ -46,7 +46,7 @@ export default EditItemModal = (props) => {
<View style={styles.container}>
<View style={{ width: '100%', flexDirection: 'row', alignItems: 'flex-start', justifyContent: 'flex-start', backgroundColor: tag.color + '22', borderRadius: 10, }}>
{product.price ? <Text style={[styles.textPrice, { color: COLORS.textW0 + 'de', }]}>{product.price}</Text> : <View />}
{product.price ? <Text style={[styles.textPrice, { color: COLORS.price, }]}>{product.price}</Text> : <View />}
<Image source={{ uri: product.image }}
style={styles.image} />
<Text style={[styles.textTags, { color: tag.color, }]}>{tag.tagName}</Text>

View File

@@ -22,9 +22,31 @@ export default EditProductModal = () => {
const [tagName, setTagName] = useState(product.tag);
const [price, setPrice] = useState(product.price.toString());
const [imageURL, setImageURL] = useState(product.image);
//tags
const [tagsList, setTagsList] = useState(tags.map((listTag) => listTag.tagName));
const [focussed, setFocussed] = useState(false);
const filterTagsList = (text) => {
let regex = new RegExp(text);
let newTagsList = tags.filter((tag) =>
regex.test(tag.tagName)
)
text !== '' ? newTagsList = newTagsList.map((tag) => tag.tagName) : newTagsList = tags.map((tag) => tag.tagName)
if (newTagsList.length === 1 && newTagsList[0] === text) {
setTagsList([]);
}
else {
setTagsList(newTagsList);
}
setTagName(text);
};
//tags
const saveModal = () => {
dispatch(editProduct(product.id, productName, tagName, price, imageURL));
let tagFound = tags.find((tag)=>tag.tagName === tagName)
dispatch(editProduct(product.id, productName, tagFound ? tagName : 'uncategorized', Number(price) ? Number(price) : 0, imageURL));
dispatch(modalToggle(product.id))
}
return (
@@ -34,7 +56,7 @@ export default EditProductModal = () => {
swipeDirection={'down'}
onSwipeComplete={saveModal}
useNativeDriverForBackdrop
style={styles.modalEditItem} >
style={styles.modalEditProduct} >
<View style={styles.container}>
<View style={{ width: '100%', flexDirection: 'row', alignItems: 'flex-start', justifyContent: 'flex-start', backgroundColor: tag.color + '22', borderRadius: 10, }}>
<Image source={{ uri: product.image }}
@@ -55,10 +77,19 @@ export default EditProductModal = () => {
<TextInput
placeholder={'Tag'}
placeholderTextColor={'grey'}
style={styles.textInput}
onChangeText={text => setTagName(text)}
style={[styles.textInput]}
value={tagName}
onChangeText={text => filterTagsList(text)}
onFocus={() => setFocussed(true)}
onEndEditing={() => setFocussed(false)}
/>
<ScrollView style={styles.dropdown} keyboardShouldPersistTaps={'always'}>
{focussed ? tagsList.map((newTag, index) =>
<TouchableOpacity key={index} onPress={() => filterTagsList(newTag)} style={styles.dropdownProduct}>
<Text style={styles.dropdownText}>{newTag}</Text>
</TouchableOpacity>
) : <View />}
</ScrollView>
</View>
<View style={styles.inputRow}>
<MaterialCommunityIcons name="currency-usd" color={COLORS.textW0 + '55'} size={30} />
@@ -71,6 +102,16 @@ export default EditProductModal = () => {
value={price}
/>
</View>
<View style={styles.inputRow}>
<MaterialCommunityIcons name="link-plus" color={COLORS.textW0 + '55'} size={30} />
<TextInput
placeholder={'Image'}
placeholderTextColor={'grey'}
style={styles.textInput}
onChangeText={text => setImageURL(text)}
value={imageURL}
/>
</View>
<TouchableOpacity style={styles.modalSaveButton} onPress={saveModal} >
<Text style={styles.modalSaveButtonText}>Save</Text>
</TouchableOpacity>
@@ -89,7 +130,7 @@ const styles = StyleSheet.create({
backgroundColor: COLORS.dp01,
alignItems: 'center',
},
modalEditItem: {
modalEditProduct: {
justifyContent: 'flex-end',
margin: 0,
padding: 0,
@@ -102,7 +143,6 @@ const styles = StyleSheet.create({
alignSelf: 'flex-start',
borderTopRightRadius: 20,
},
textInput: {
height: 30,
@@ -124,7 +164,6 @@ const styles = StyleSheet.create({
alignItems: 'flex-start',
justifyContent: 'flex-start',
width: '100%',
marginLeft: 5,
},
textItem: {
width: '100%',
@@ -138,24 +177,6 @@ const styles = StyleSheet.create({
color: COLORS.textW0 + 'ff',
backgroundColor: '#000' + '3',
},
textPrice: {
paddingLeft: '52%',
position: 'absolute',
fontSize: 18,
color: COLORS.textW1,
backgroundColor: '#000' + '5',
padding: 5,
width: '100%',
borderTopRightRadius: 10,
},
textTags: {
left: 8,
marginTop: 35,
fontFamily: 'Roboto',
fontSize: 18,
color: COLORS.textW1,
},
modalSaveButtonText: {
opacity: 0.8,
fontSize: 20,
@@ -165,7 +186,35 @@ const styles = StyleSheet.create({
modalSaveButton: {
marginTop: 10,
marginBottom: 10,
}
},
dropdown: {
zIndex: 1,
position: 'absolute',
maxHeight: 100,
width: 150,
top: 40,
left: 10,
borderRadius: 10,
backgroundColor: COLORS.dp16 + 'ee',
},
dropdownProduct: {
zIndex: 1,
width: 150,
minHeight: 20,
borderBottomWidth: 1.0,
borderColor: '#666' + '5',
},
dropdownText: {
zIndex: 1,
left: 10,
fontSize: 17,
color: COLORS.textW0 + 'ee',
},
})

View File

@@ -1,7 +1,7 @@
import { createSlice } from '@reduxjs/toolkit';
const initialState = [
{ tagName: 'uncathegorized', color: '#253f34' },
{ tagName: 'uncategorized', color: '#253f34' },
{ tagName: 'Meat', color: '#ef5350' },
{ tagName: 'Vegetables & fruit', color: '#BDD684' },
{ tagName: 'Meal', color: '#FA9600' },

View File

@@ -102,10 +102,10 @@ function GroceryList() {
const compareFunction = (a,b) => {
const newA = products.find((product=>product.id === a.productId))
let tagA
newA ? tagA = newA.tag : tagA = "uncathegorized"
newA ? tagA = newA.tag : tagA = "uncategorized"
const newB = products.find((product=>product.id === b.productId))
let tagB
newB ? tagB = newB.tag : tagB = "uncathegorized"
newB ? tagB = newB.tag : tagB = "uncategorized"
return tagA.localeCompare(tagB)
}

View File

@@ -12,7 +12,7 @@ export const COLORS = {
secondary: '#f2aeac', //secondary
secondaryVar: '#ffffff', //secondary variant
price: '#C6A337',
price: '#ece1bc',
//layout colors #DAE9FF