From 8a8ae62f20f3cf588b780a16a2dc3c6caacf0e4e Mon Sep 17 00:00:00 2001 From: Hajar RAHMOUNI Date: Fri, 3 Nov 2023 20:07:17 +0100 Subject: [PATCH] feat: swipeout to delete item from cart --- client/package-lock.json | 34 ++++++++++++ client/package.json | 1 + client/screens/CartScreen.tsx | 97 +++++++++++++++++++++++------------ 3 files changed, 99 insertions(+), 33 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index 81b1771..4cd4e69 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -21,6 +21,7 @@ "react": "18.2.0", "react-dom": "18.2.0", "react-native": "0.71.14", + "react-native-swipeout": "^2.3.6", "react-native-vector-icons": "^10.0.0", "react-native-web": "~0.18.11" }, @@ -19745,6 +19746,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/raf": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", + "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", + "dependencies": { + "performance-now": "^2.1.0" + } + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -20232,6 +20241,17 @@ "react-native": "*" } }, + "node_modules/react-native-swipeout": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/react-native-swipeout/-/react-native-swipeout-2.3.6.tgz", + "integrity": "sha512-t9suUCspzck4vp2pWggWe0frS/QOtX6yYCawHnEes75A7dZCEE74bxX2A1bQzGH9cUMjq6xsdfC94RbiDKIkJg==", + "deprecated": "Package no longer supported. Use at your own risk or consider using https://github.com/software-mansion/react-native-gesture-handler", + "dependencies": { + "create-react-class": "^15.6.0", + "prop-types": "^15.5.10", + "react-tween-state": "^0.1.5" + } + }, "node_modules/react-native-vector-icons": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-10.0.1.tgz", @@ -20349,6 +20369,15 @@ "react": "^16.0.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/react-tween-state": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/react-tween-state/-/react-tween-state-0.1.5.tgz", + "integrity": "sha512-sJQpjsdn0wjlDIUpfpb7jQGnOG8hAEW2e8k0KPA+xmf5KFa6Xat2JldbmxBhaqP0S/uIXhVE5ymKyH/b9X8nYA==", + "dependencies": { + "raf": "^3.1.0", + "tween-functions": "^1.0.1" + } + }, "node_modules/read-chunk": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-3.2.0.tgz", @@ -23028,6 +23057,11 @@ "domino": "^2.1.6" } }, + "node_modules/tween-functions": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tween-functions/-/tween-functions-1.2.0.tgz", + "integrity": "sha512-PZBtLYcCLtEcjL14Fzb1gSxPBeL7nWvGhO5ZFPGqziCcr8uvHp0NDmdjBchp6KHL+tExcg0m3NISmKxhU394dA==" + }, "node_modules/tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", diff --git a/client/package.json b/client/package.json index 886df61..7ae3d6b 100644 --- a/client/package.json +++ b/client/package.json @@ -22,6 +22,7 @@ "react": "18.2.0", "react-dom": "18.2.0", "react-native": "0.71.14", + "react-native-swipeout": "^2.3.6", "react-native-vector-icons": "^10.0.0", "react-native-web": "~0.18.11" }, diff --git a/client/screens/CartScreen.tsx b/client/screens/CartScreen.tsx index 8a03746..e36c0e8 100644 --- a/client/screens/CartScreen.tsx +++ b/client/screens/CartScreen.tsx @@ -1,18 +1,18 @@ import React, { useEffect, useState } from 'react'; -import { View, Text, FlatList, Button } from 'react-native'; +import { View, Text, Button, FlatList } from 'react-native'; import { useNavigation } from '@react-navigation/native'; import Styles from '../styles/Style'; import Icon from 'react-native-vector-icons/MaterialIcons'; -import * as SQLite from 'expo-sqlite'; import db from '../database/db'; import Constants from 'expo-constants'; +import Swipeout from 'react-native-swipeout'; function CartScreen() { const navigation = useNavigation(); const [items, setItems] = useState([]); const [totalPrice, setTotalPrice] = useState(0); - const apiUrl = Constants.expoConfig.extra.apiUrl; + const apiUrl = Constants.manifest.extra.apiUrl; const getItemsWithQuantities = () => { return new Promise((resolve, reject) => { @@ -33,39 +33,70 @@ function CartScreen() { }, []); const calculateTotalPrice = (items) => { - const cartItems = items.map((item) => ({ - item_id: item.id, - quantity: item.quantity, - })); - const requestOptions = { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(cartItems), - }; - fetch(`${apiUrl}/items/calculate-total`, requestOptions) - .then((response) => { - if (!response.ok) { - throw new Error('Response not valid'); - } - return response.json(); - }) - .then((total) => { - setTotalPrice((total / 100).toFixed(2)); - }) - .catch((error) => { - console.error('Error calculating total:', error); - }); + const cartItems = items.map((item) => ({ + item_id: item.id, + quantity: item.quantity, + })); + const requestOptions = { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(cartItems), }; + fetch(`${apiUrl}/items/calculate-total`, requestOptions) + .then((response) => { + if (!response.ok) { + throw new Error('Response not valid'); + } + return response.json(); + }) + .then((total) => { + setTotalPrice((total / 100).toFixed(2)); + }) + .catch((error) => { + console.error('Error calculating total:', error); + }); + }; + const deleteItem = (itemId) => { + db.transaction((tx) => { + tx.executeSql( + 'DELETE FROM items WHERE id = ?', + [itemId], + () => { + // Update the list of items after deletion + const updatedItems = items.filter((item) => item.id !== itemId); + setItems(updatedItems); + calculateTotalPrice(updatedItems); + }, + (error) => { + console.error('Error deleting item from items:', error); + } + ); + }); + }; - const renderItem = ({ item }) => ( - - {item.name} ({item.quantity}) - {(item.price / 100).toFixed(2)} € - - ); + const renderItem = ({ item }) => { + const swipeoutBtns = [ + { + text: 'Delete', + backgroundColor: 'red', + onPress: () => deleteItem(item.id), + }, + ]; + + return ( + + + + {item.name} ({item.quantity}) + + {(item.price / 100).toFixed(2)} € + + + ); + }; return ( -- GitLab