Skip to content

Commit

Permalink
Merge pull request #47 from andreasalstrup/edit-list-item
Browse files Browse the repository at this point in the history
Added edit on long press to list view
  • Loading branch information
UnluckyBird authored Nov 29, 2023
2 parents 68bf493 + bcbf6ad commit e04a7c3
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 18 deletions.
73 changes: 55 additions & 18 deletions app/(tabs)/(index)/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Button, Pressable, StyleSheet, TextInput, useColorScheme } from 'react-native';
import { Button, Pressable, StyleSheet, TextInput, TouchableOpacity, useColorScheme } from 'react-native';
import Modal from "react-native-modal";
import { Text, View, } from '../../../components/Themed';
import { useState } from 'react';
import { FlatList } from 'react-native-gesture-handler';
import { FlatList, Gesture, GestureDetector } from 'react-native-gesture-handler';
import { FontAwesome5 } from '@expo/vector-icons';
import CheckBox from 'expo-checkbox';
import Swipeable from 'react-native-gesture-handler/Swipeable';
Expand Down Expand Up @@ -75,7 +75,7 @@ function rightSwipeAction() {

export default function ToBeBoughtScreen() {
const colorScheme = useColorScheme() ?? 'light';
const [isModalAddItemVisible, setIsModalAddItemVisible] = useState(false);
const [isModalAddOrEditItemVisible, setIsModalAddOrEditItemVisible] = useState(false);
const [isModalDeleteVisible, setIsModalDeleteVisible] = useState(false);
const [products, setProducts] = useState(seedData)

Expand All @@ -84,20 +84,49 @@ export default function ToBeBoughtScreen() {
const [alreadyBought, setAlreadyBought] = useState(false);
const [price, setPrice] = useState('0');

const [itemToEdit, setItemToEdit] = useState<number | undefined>()
const [itemToDelete, setItemToDelete] = useState(0)

const swipeableRows : Swipeable[] = []

const handleModalAddItem = () => setIsModalAddItemVisible(() => !isModalAddItemVisible);
const handleModalAddOrEditItem = () => { console.log(!isModalAddOrEditItemVisible); setIsModalAddOrEditItemVisible(() => !isModalAddOrEditItemVisible); }
const handleModalDelete = () => setIsModalDeleteVisible(() => !isModalDeleteVisible);
const handleCheckbox = () => setAlreadyBought(() => !alreadyBought);

const clearProduct = () => {
setProductName('')
setSelectedUsers(usersDropdown.map((user) => user.value))
setAlreadyBought(false)
setPrice('0')
setItemToEdit(undefined)
}

const editProduct = (index : number) => {
setProductName(products[index].name)
setSelectedUsers(products[index].data.users.map((user) => user.name))
}
const addProduct = () => {

const saveEditedProduct = () => {
setProducts(products.map((product, index) => {
if (itemToEdit && product === products[itemToEdit]) {
return { ...product,
name: productName,
data: {
...product.data,
users: selectedUsers.map(user => ({name: user})),
bought: alreadyBought ? {user: "Me", date: moment().format('YYYY.MM.DD'), price: Number(price)} : undefined
}
}
}
else {
return product;
}
}))

handleModalAddOrEditItem()
}

const saveAddedProduct = () => {
const time = moment().format('YYYY.MM.DD');
const newProduct = {
name: productName,
Expand All @@ -107,17 +136,17 @@ export default function ToBeBoughtScreen() {
bought: alreadyBought ? {user: "Me", date: time, price: Number(price)} : undefined
}
}
if(newProduct.data.bought === undefined){
if(newProduct.data.bought === undefined) {
//Add to GUN here
console.log(newProduct.name + ' added')
}
else{
else {
//Move to GUN bought list here
console.log(newProduct.name + ' bought by ' + newProduct.data.bought.user)
}
setProducts(products => [...products, newProduct])

handleModalAddItem()
handleModalAddOrEditItem()
}

function swipeHandler(dir: 'left' | 'right', index: number) {
Expand Down Expand Up @@ -159,13 +188,21 @@ export default function ToBeBoughtScreen() {
renderLeftActions={leftSwipeAction}
renderRightActions={rightSwipeAction}
onSwipeableOpen={(dir) => swipeHandler(dir, index)}>
<View style={[styles.container,
{backgroundColor: index % 2 == 0 ? Colors[colorScheme].listBackgroundColor1 : Colors[colorScheme].listBackgroundColor2}]}>
<View style={styles.item}>
<Text style={styles.itemText}>{item.name}</Text>
</View>
<Text style={styles.infoText}>Added by {item.data.added.user} {item.data.added.date}</Text>
</View>
<TouchableOpacity
activeOpacity={0.5}>
<GestureDetector gesture={Gesture.LongPress().onStart(e => {
setItemToEdit(index)
editProduct(index)
handleModalAddOrEditItem()
})}>
<View style={[styles.container, {backgroundColor: index % 2 == 0 ? Colors[colorScheme].listBackgroundColor1 : Colors[colorScheme].listBackgroundColor2}]}>
<View style={styles.item}>
<Text style={styles.itemText}>{item.name}</Text>
</View>
<Text style={styles.infoText}>Added by {item.data.added.user} {item.data.added.date}</Text>
</View>
</GestureDetector>
</TouchableOpacity>
</Swipeable>
)
}
Expand All @@ -177,7 +214,7 @@ export default function ToBeBoughtScreen() {
data={products}
renderItem={renderItem}
/>
<Modal animationIn='zoomIn' animationOut='zoomOut' isVisible={isModalAddItemVisible} onBackdropPress={handleModalAddItem} onModalHide={clearProduct}>
<Modal animationIn='zoomIn' animationOut='zoomOut' isVisible={isModalAddOrEditItemVisible} onBackdropPress={() => setIsModalAddOrEditItemVisible(false)} onModalHide={clearProduct}>
<View style={ styles.addItemModal }>
<Text>Product</Text>
<TextInput
Expand Down Expand Up @@ -229,7 +266,7 @@ export default function ToBeBoughtScreen() {
editable
/> : null}

<Button color='#5CBCA9' title="Add Product" onPress={addProduct} />
<Button color='#5CBCA9' title={itemToEdit ? "Edit Product" : "Add Product"} onPress={itemToEdit ? saveEditedProduct : saveAddedProduct} />
</View>
</Modal>
<Modal
Expand Down Expand Up @@ -257,7 +294,7 @@ export default function ToBeBoughtScreen() {
size={50}
color={Colors[colorScheme].background}
/>}}
onPress={handleModalAddItem}
onPress={handleModalAddOrEditItem}
buttonColor='#5CBCA9'
position='center'
size={70}/>
Expand Down
83 changes: 83 additions & 0 deletions components/AreYouSureModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { Pressable, StyleSheet } from "react-native";
import Modal from "react-native-modal";
import { Text, View, } from './Themed';

type AreYouSureProps = {
title: string,
text: string,
isVisible: boolean,
onBackdropPress?: () => void,
onYes?: () => void,
onNo?: () => void
};

const renderButton = (text: string, onPress?: () => void) => {
return (
<Pressable style={[styles.button, { backgroundColor: text === 'Yes' ? '#5CBCA9' : '#E35F52' }]} onPress={onPress}>
<Text style={styles.buttonText}>{text}</Text>
</Pressable>
);
};

export default function AreYouSureModal(props: AreYouSureProps) {
return (
<View style={styles.container}>
<Modal
animationIn='zoomIn'
animationOut='zoomOut'
isVisible={props.isVisible}
onBackdropPress={props.onBackdropPress}>
<View style={styles.modalContainer}>
<View style={styles.modalContent}>
<Text style={styles.modalTitleText}>{props.title}</Text>
<Text style={styles.modalContentText}>{props.text}</Text>
<View style={styles.buttonContainer}>
{renderButton('Yes', props.onYes)}
{renderButton('No', props.onNo)}
</View>
</View>
</View>
</Modal>
</View>
);
}

const styles = StyleSheet.create({
container: {
flex: 1
},
modalContainer: {
justifyContent: 'center',
backgroundColor: 'rgba(0, 0, 0, 0.5)',
},
modalContent: {
padding: 20,
borderRadius: 10,
height: 250
},
modalTitleText: {
fontSize: 30,
},
modalContentText: {
fontSize: 16,
flex: 1
},
buttonContainer: {
flexDirection: 'row',
justifyContent: 'space-evenly',
padding: 10,
},
button: {
alignItems: 'center',
justifyContent: 'center',
paddingVertical: 12,
paddingHorizontal: 24,
borderRadius: 4,
elevation: 3,
width: "40%",
},
buttonText: {
color: 'white',
fontSize: 16,
}
});

0 comments on commit e04a7c3

Please sign in to comment.