From 2ead23c98fa3b25788ec3a01c7db37c345e62acb Mon Sep 17 00:00:00 2001 From: "mathias.fernandez.bo" <mathias.fernandez.bo@fing.edu.uy> Date: Tue, 29 Nov 2022 06:18:43 -0300 Subject: [PATCH 1/6] cart, reviews, textarea, fixes android --- .idea/.gitignore | 3 + .idea/frontmobile.iml | 14 ++ .idea/modules.xml | 8 + .idea/vcs.xml | 6 + src/components/Navigation/SideMenu.tsx | 21 +- src/components/SliderSlick.tsx | 6 +- src/screens/ShoppingPost.tsx | 111 ++++++++--- src/screens/SignUp.tsx | 4 +- src/screens/UserProfile.tsx | 111 ++++++----- src/screens/customer/Checkout.tsx | 4 +- src/screens/customer/GiveReview.tsx | 263 ++++++++++++++----------- src/screens/customer/Profile.tsx | 5 +- src/screens/customer/Purchase.tsx | 9 +- src/screens/customer/Review.tsx | 54 +++-- src/screens/customer/Settings.tsx | 8 +- src/screens/customer/ShoppingCart.tsx | 137 ++++++++----- src/services/Requests.tsx | 7 +- urubuy.d.ts | 14 ++ 18 files changed, 514 insertions(+), 271 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/frontmobile.iml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/frontmobile.iml b/.idea/frontmobile.iml new file mode 100644 index 0000000..697945a --- /dev/null +++ b/.idea/frontmobile.iml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module type="JAVA_MODULE" version="4"> + <component name="FacetManager"> + <facet type="android" name="Android"> + <configuration /> + </facet> + </component> + <component name="NewModuleRootManager" inherit-compiler-output="true"> + <exclude-output /> + <content url="file://$MODULE_DIR$" /> + <orderEntry type="jdk" jdkName="Android API 32 Platform" jdkType="Android SDK" /> + <orderEntry type="sourceFolder" forTests="false" /> + </component> +</module> \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..2c487de --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="ProjectModuleManager"> + <modules> + <module fileurl="file://$PROJECT_DIR$/.idea/frontmobile.iml" filepath="$PROJECT_DIR$/.idea/frontmobile.iml" /> + </modules> + </component> +</project> \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="VcsDirectoryMappings"> + <mapping directory="" vcs="Git" /> + </component> +</project> \ No newline at end of file diff --git a/src/components/Navigation/SideMenu.tsx b/src/components/Navigation/SideMenu.tsx index ac61b00..46e7db7 100644 --- a/src/components/Navigation/SideMenu.tsx +++ b/src/components/Navigation/SideMenu.tsx @@ -1,5 +1,5 @@ import React, { useState } from "react"; -import { Alert, View, Text, TouchableOpacity } from "react-native"; +import { Alert, View, Text, TouchableOpacity, Platform } from "react-native"; import Notification from "../../screens/Notification"; import ShoppingPost from "../../screens/ShoppingPost"; import _ShoppingCart from "../../screens/customer/ShoppingCart"; @@ -22,7 +22,6 @@ import Likes from "../../screens/customer/Likes"; import ReviewSeller from "../../screens/customer/GiveReview"; import CheckoutScreen from "../../screens/customer/Checkout"; import Addresses from "../../screens/customer/Addresses"; -import SettingNotifications from "../SettingNotifications"; const Drawer = createDrawerNavigator(); @@ -117,7 +116,16 @@ export default function SideMenu() { ) : null} {user && cartCounter > 0 ? ( <View className="bg-[#ff1717] items-center justify-center rounded-3xl h-[17] w-[17] absolute right-[8] top-[-10]"> - <Text className="items-center justify-center text-[#ffffff] text-[14px]"> {cartCounter} </Text> + <Text + className={ + Platform.OS === "android" + ? "text-[#ffffff] text-[14px] bottom-[1.8px]" + : "items-center justify-center text-[#ffffff] text-[14px]" + } + > + {" "} + {cartCounter}{" "} + </Text> </View> ) : null} </View> @@ -127,10 +135,11 @@ export default function SideMenu() { {user === "" || user === undefined ? ( <> <Drawer.Screen - name="Ingresar" + name="Login" component={Login} options={{ headerTintColor: "#fff", + headerTitle: "Ingresar", drawerLabelStyle: dark ? { color: "white" } : null, headerStyle: { backgroundColor: "#0c35c5", @@ -143,7 +152,7 @@ export default function SideMenu() { /> <Drawer.Screen - name="Registrarse" + name="SignUp" component={SignUp} options={{ headerTintColor: "#fff", @@ -286,7 +295,7 @@ export default function SideMenu() { }, drawerItemStyle: { display: "none" }, headerLeft: (focus) => ( - <TouchableOpacity onPress={() => navigation.navigate("Home") as never}> + <TouchableOpacity onPress={() => navigation.goBack()}> <ArrowLeft size={24} style={{ padding: 10, marginLeft: 10 }} color={focus ? "#fff" : "grey"} /> </TouchableOpacity> ), diff --git a/src/components/SliderSlick.tsx b/src/components/SliderSlick.tsx index 0c6dccf..7f34809 100644 --- a/src/components/SliderSlick.tsx +++ b/src/components/SliderSlick.tsx @@ -14,15 +14,15 @@ const SliderSlick: React.FC<ProductImages> = ({ pictures }) => { let screenH = Dimensions.get("window").height; return ( <View className="h-[475px]"> - <Slick> + <Slick dotStyle={{ backgroundColor: "white" }} activeDotColor={"#cf8c40"}> {pictures && pictures.length > 0 ? ( pictures.map((x, k) => ( - <View key={Math.random() * k + 100} className="w-full h-full "> + <View key={Math.random() * k + 100} className="w-full h-full"> <ImageZoom key={Math.random() * k + 100} uri={x.includes("data:image") ? x : `data:image/jpg;base64,${x}`} containerStyle={{ alignItems: "center", justifyContent: "center", flex: 1, marginTop: 4, padding: 4 }} - style={{ resizeMode: "contain", width: screenW, height: screenH, borderRadius: 40 }} + style={{ resizeMode: "contain", width: screenW, height: screenH }} /> </View> )) diff --git a/src/screens/ShoppingPost.tsx b/src/screens/ShoppingPost.tsx index 05d3bed..215c152 100644 --- a/src/screens/ShoppingPost.tsx +++ b/src/screens/ShoppingPost.tsx @@ -3,17 +3,27 @@ import React, { useEffect, useState } from "react"; import { Alert, ImageBackground, Platform, ScrollView, Text, TouchableOpacity, View } from "react-native"; import CustomButton from "../components/CustomButton"; import SliderSlick from "../components/SliderSlick"; -import { addToCart, getData, getShoppingPostById, storeData } from "../services/Requests"; +import { addToCart, getData, getSellerProfile, getShoppingPostById } from "../services/Requests"; import CustomReport, { ReportIOS } from "../components/Report/CustomReport"; import Loading from "../components/Loading"; import { TShoppingPost } from "../../urubuy"; -import { Package } from "phosphor-react-native"; +import { Package, ShoppingCartSimple } from "phosphor-react-native"; +import StarSvg from "../components/Svgs/StarSvg"; +import { useColorScheme } from "nativewind"; + +type SellerRating = { + username: string; + averageRating: number; +}; export default function ShoppingPost(props: any) { const nav = useNavigation(); const [shoppingPost, setShoppingPost] = useState<TShoppingPost | undefined>(undefined); const [promptAndroid, setPromptAndroid] = useState(false); const [activeUser, setActiveUser] = useState<string | undefined>(undefined); + const [seller, setSeller] = useState<SellerRating | undefined>(undefined); + const { colorScheme } = useColorScheme(); + const dark = colorScheme === "dark"; useEffect(() => { const unsubscribe = nav.addListener("blur", () => { @@ -26,6 +36,7 @@ export default function ShoppingPost(props: any) { getShoppingPostById(props.route.params.id) .then((res) => { setShoppingPost(res.data); + handleShowSeller(res.data.sellerEmail); }) .catch((err) => console.log(err.response.data)); @@ -44,21 +55,7 @@ export default function ShoppingPost(props: any) { const handleAddCart = async () => { if (activeUser) { - // if logged persist addToCart(activeUser, Number(shoppingPost?.id)); - - let cart = await getData("myCart"); - if (!cart) storeData("myCart", "1"); - else storeData("myCart", String(Number(cart) + 1)); - - /* if (myCart === undefined || myCart === null) { - storeData("myCart", shoppingPost!.id); - } else { - if (!myCart.includes(shoppingPost!.id)) { - myCart = myCart + "," + shoppingPost!.id; - storeData("myCart", myCart as string); - } - }*/ Alert.alert("Agregado!"); } }; @@ -76,6 +73,18 @@ export default function ShoppingPost(props: any) { else console.log("seller wrong"); } + function handleShowSeller(email: string) { + getSellerProfile(email).then((res) => { + if (res.status === 200) { + setSeller({ username: res.data.username, averageRating: res.data.averageRating }); + } + }); + } + + function handleLogin() { + nav.navigate("Login" as never); + } + return ( <View className="items-center justify-center flex-1 bg-[#fff]"> <ImageBackground @@ -87,13 +96,21 @@ export default function ShoppingPost(props: any) { <CustomReport android={promptAndroid} /> {shoppingPost ? ( <ScrollView showsVerticalScrollIndicator={false}> - <View className="flex-row items-center justify-evenly"> - <Text className="text-center font-bold text-[19px] mt-2 text-dark-mode-text"> - {shoppingPost.category.name} - </Text> + <View className="flex-row items-center justify-between"> <TouchableOpacity onPress={() => handleProfile(shoppingPost.sellerEmail)}> - <Text className="text-center font-bold text-[19px] mt-2 text-[#cf8c40]"> - {shoppingPost.sellerEmail} + <Text className="text-center font-bold text-[19px] mt-2 ml-5 text-[#cf8c40]">{seller?.username!}</Text> + </TouchableOpacity> + + <TouchableOpacity + className={Platform.OS === "android" ? "mr-3" : ""} + onPress={() => alert("todo: calificaciones del seller")} + > + <Text className="text-center font-bold text-[19px] mt-2 text-[#cf8c40] scale-[.65]"> + {[...Array(seller?.averageRating)].map((i, k) => ( + <View key={k}> + <StarSvg color={"#f1c533"} /> + </View> + ))} </Text> </TouchableOpacity> </View> @@ -133,7 +150,12 @@ export default function ShoppingPost(props: any) { {shoppingPost.hasDelivery ? ( <View className="flex-row"> <Text className="font-bold text-[17px] mt-2 text-dark-mode-text">Producto con delivery</Text> - <Package size={20} weight="duotone" color="#cf8c40" style={{ top: 4.5 }} /> + <Package + size={20} + weight="duotone" + color="#cf8c40" + style={Platform.OS === "ios" ? { top: 4.5 } : { top: 10.5 }} + /> </View> ) : null} </View> @@ -148,6 +170,18 @@ export default function ShoppingPost(props: any) { <Text className="flex-wrap mt-3 p-3 font-semibold text-[17px] text-dark-mode-text"> {shoppingPost.description} </Text> + <TouchableOpacity + className={Platform.OS === "android" ? "ml-5" : ""} + onPress={() => alert("todo: calificaciones del producto")} + > + <Text className="text-left font-bold text-[19px] mt-2 text-[#cf8c40] scale-[.65]"> + {[...Array(shoppingPost?.averageRating)].map((i, k) => ( + <View key={k}> + <StarSvg color={"#f1c533"} /> + </View> + ))} + </Text> + </TouchableOpacity> </View> {activeUser ? ( @@ -158,6 +192,14 @@ export default function ShoppingPost(props: any) { value="Agregar al carrito" style={{}} /> + <View + className={Platform.select({ + ios: "absolute bottom-[9.5px] left-[21%]", + android: "absolute bottom-[9.5px] left-[21%]", + })} + > + <ShoppingCartSimple size={19} weight="duotone" color="white" /> + </View> {false && ( <CustomButton isDisabled={false} @@ -167,11 +209,28 @@ export default function ShoppingPost(props: any) { /> )} </> - ) : null} + ) : ( + <> + <CustomButton + isDisabled={false} + onPress={() => handleLogin()} + value="Iniciar sesión y añadir" + style={{}} + /> + <View + className={Platform.select({ + ios: "absolute bottom-[9.5px] left-[21%]", + android: "absolute bottom-[9.5px] left-[21%]", + })} + > + <ShoppingCartSimple size={19} weight="duotone" color="white" /> + </View> + </> + )} </ScrollView> ) : ( - <View className="flex items-center justify-center"> - <Loading text="Cargando publicación" bg={true} /> + <View className="flex mx-auto my-auto"> + <Loading text="Cargando publicación..." bg={true} /> </View> )} </ImageBackground> diff --git a/src/screens/SignUp.tsx b/src/screens/SignUp.tsx index 566826c..3077b27 100644 --- a/src/screens/SignUp.tsx +++ b/src/screens/SignUp.tsx @@ -50,6 +50,8 @@ export default function SignUp() { averageRating: 0, addresses: userAddressess, picture: image, + givenUserReviews: undefined, + receivedUserReviews: undefined, }; let userKc: TUserKC = { email: email, @@ -253,7 +255,7 @@ export default function SignUp() { </View> )} - <CustomButton isDisabled={!validPasswords} onPress={handleRegister} value="Registrarse" style={{}} /> + <CustomButton isDisabled={!validPasswords} onPress={handleRegister} value="SignUp" style={{}} /> </ScrollView> </KeyboardAvoidingView> </> diff --git a/src/screens/UserProfile.tsx b/src/screens/UserProfile.tsx index 3b2e568..6fba099 100644 --- a/src/screens/UserProfile.tsx +++ b/src/screens/UserProfile.tsx @@ -1,14 +1,16 @@ import React, { useEffect, useState } from "react"; import { Text, View, Image, Alert } from "react-native"; -import { getSellerProfile } from "../services/Requests"; +import { getCustomerProfile, getSellerProfile } from "../services/Requests"; import StarSvg from "../components/Svgs/StarSvg"; import { useNavigation } from "@react-navigation/core"; import Loading from "../components/Loading"; import { useColorScheme } from "nativewind"; -import { TSeller } from "../../urubuy"; +import { TSeller, TCustomer } from "../../urubuy"; function UserProfile(props: any) { - const [user, setUser] = useState<TSeller | undefined>(undefined); + const [seller, setSeller] = useState<TSeller | undefined>(undefined); + const [customer, setCustomer] = useState<TCustomer | undefined>(undefined); + const nav = useNavigation(); const [loading, setLoading] = useState(false); const { colorScheme } = useColorScheme(); @@ -28,62 +30,83 @@ function UserProfile(props: any) { .then((res) => { if (res.status === 200) { let myUser: TSeller = res.data; - setUser(myUser); - } else console.error("getting profile"); + setSeller(myUser); + } else console.error("getting s profile"); }) .catch((err) => { console.log(err.response.data); - if (user === undefined) Alert.alert("Seller ??"); + if (seller === undefined) { + getCustomerProfile(props.route.params.email) + .then((res) => { + if (res.status === 200) { + let myUser: TCustomer = res.data; + setCustomer(myUser); + } else console.error("getting c profile"); + }) + .catch((err) => { + console.log(err.response.data); + Alert.alert("user no encontrado"); + nav.canGoBack(); + }); + } }) .finally(() => { setLoading(false); }); }; + const renderProfile = (user: TCustomer | TSeller) => { + return ( + <> + {user?.picture !== undefined && user?.picture !== "" && user?.picture !== null ? ( + <Image + source={ + user?.picture.includes("data:image") + ? { uri: user?.picture } + : { uri: `data:image/jpg;base64,${user?.picture}` } + } + className="w-[150px] h-[150px] mt-[35px] ml-3 rounded-full" + /> + ) : ( + <Image + source={require("../../assets/placeholder.png")} + resizeMode="contain" + className="w-[150px] h-[250px] ml-3" + /> + )} + + <View className="max-h-[250px] max-w-[250px] absolute top-[70] left-[160] border-[black]"> + <Text className="text-[black] dark:text-dark-mode-text text-[20px] font-semibold ml-[15px]"> + {(user as TSeller) ? (user as TSeller).firstName + " " + (user as TSeller).lastName : null} + </Text> + <Text className="text-[black] dark:text-dark-mode-text text-[15px] font-semibold ml-[15px] mt-[15px] p-[1]"> + {user?.email} + </Text> + + <View className="flex-row m-[10px] p-[2]"> + {[...Array(user?.averageRating)].map((i, k) => ( + <View key={k}> + <StarSvg color={dark ? "#f1c533" : "#0c35c5"} /> + </View> + ))} + </View> + </View> + </> + ); + }; + return ( <> <View className="flex-1 dark:bg-dark-mode-bg"> {loading ? ( <View className="items-center justify-center flex-1"> - <Loading text="Cargando perfil" bg={false} /> + <Loading text="Cargando perfil" bg={true} /> </View> - ) : ( - <> - {user?.picture !== undefined && user?.picture !== "" && user?.picture !== null ? ( - <Image - source={ - user?.picture.includes("data:image") - ? { uri: user?.picture } - : { uri: `data:image/jpg;base64,${user?.picture}` } - } - className="w-[150px] h-[150px] mt-[35px] ml-3 rounded-full" - /> - ) : ( - <Image - source={require("../../assets/placeholder.png")} - resizeMode="contain" - className="w-[150px] h-[250px] ml-3" - /> - )} - - <View className="max-h-[250px] max-w-[250px] absolute top-[70] left-[160] border-[black]"> - <Text className="text-[black] dark:text-dark-mode-text text-[20px] font-semibold ml-[15px]"> - {user?.firstName} {user?.lastName} - </Text> - <Text className="text-[black] dark:text-dark-mode-text text-[15px] font-semibold ml-[15px] mt-[15px] p-[1]"> - {user?.email} - </Text> - - <View className="flex-row m-[10px] p-[2]"> - {[...Array(user?.averageRating)].map((i, k) => ( - <View key={k}> - <StarSvg color={dark ? "#f1c533" : "#0c35c5"} /> - </View> - ))} - </View> - </View> - </> - )} + ) : customer ? ( + renderProfile(customer) + ) : seller ? ( + renderProfile(seller) + ) : null} </View> </> ); diff --git a/src/screens/customer/Checkout.tsx b/src/screens/customer/Checkout.tsx index f976e22..02d1b61 100644 --- a/src/screens/customer/Checkout.tsx +++ b/src/screens/customer/Checkout.tsx @@ -58,7 +58,6 @@ export default function Checkout(props: any) { setLoadingRedirect(true); await removeData("cartId"); await removeData("hasCheckout"); - await removeData("myCart"); setTimeout(() => { nav.navigate("Home" as never); }, 4500); @@ -70,6 +69,7 @@ export default function Checkout(props: any) { const handlePay = () => { if (checkout?.total) { console.log(checkout?.total); + // total no puede salir con mas de 2 decimales openLink(checkout?.total); } else console.log("total failed"); }; @@ -249,7 +249,7 @@ export default function Checkout(props: any) { <View className="flex-row justify-between"> <Text className="dark:text-dark-mode-text text-center text-[28px] font-semibold ml-1 p-1">Total</Text> <Text className="dark:text-dark-mode-text text-center text-[28px] font-semibold mr-1 p-1"> - USD {checkout?.total} + USD {checkout?.total.toFixed(1)} </Text> </View> </View> diff --git a/src/screens/customer/GiveReview.tsx b/src/screens/customer/GiveReview.tsx index ec8c520..105593c 100644 --- a/src/screens/customer/GiveReview.tsx +++ b/src/screens/customer/GiveReview.tsx @@ -1,15 +1,16 @@ import { useFocusEffect } from "@react-navigation/core"; import { ChatCircleDots, ImageSquare, Star, X, XCircle } from "phosphor-react-native"; -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; import { View, Text, TouchableOpacity, Modal, Image, ScrollView, Alert } from "react-native"; import { useColorScheme } from "nativewind"; import * as ImagePicker from "expo-image-picker"; import CustomButton from "../../components/CustomButton"; import SliderSlick from "../../components/SliderSlick"; -import { TReview } from "../../../urubuy"; +import { TReview, TUserReview } from "../../../urubuy"; import { Divider, TextInput } from "react-native-paper"; import Loading from "../../components/Loading"; import myStyle from "../../../assets/styles"; +import { getData, reviewSeller } from "../../services/Requests"; type GReview = { titlePhoto: string; @@ -32,11 +33,24 @@ export default function GiveReview(props: any) { const uriStarFilled = Image.resolveAssetSource(starFilled).uri; const { colorScheme } = useColorScheme(); const dark = colorScheme === "dark"; + const [inputHeight, setInputHeight] = useState(0); + const [email, setEmail] = useState(""); + const [sellerEmail, setSellerEmail] = useState(""); useFocusEffect(() => { setPurchaseId(props.route.params.id); + setSellerEmail(props.route.params.seller); }); + useEffect(() => { + getInitialData(); + }, []); + + const getInitialData = async () => { + let email = await getData("email"); + setEmail(email!); + }; + const handleSeller = () => { setShowReviewSeller(!showReviewSeller); }; @@ -99,19 +113,41 @@ export default function GiveReview(props: any) { }; let handleReview = () => { - let review: TReview = { - id: "", - rating: defaultRating, - description: reviewComment, - base64Images: images!, - date: Date.now().toString(), - }; - console.log(review.description + "\n" + review.rating + "\n" + review.base64Images.length); - setReviewComment(""); - setImages([]); - setDefaultRating(3); - Alert.alert("Gracias por calificar"); - showReviewProduct ? setShowReviewProduct(!showReviewProduct) : setShowReviewSeller(!showReviewSeller); + if (showReviewSeller === true) { + let sellerReview: TUserReview = { + id: "", + rating: defaultRating, + description: reviewComment, + date: "", + customerEmail: email, + sellerEmail: sellerEmail, + from: "CUSTOMER", + }; + reviewSeller(sellerReview) + .then((res) => { + if (res.status === 200) Alert.alert("Gracias por calificar"); + }) + .catch((err) => { + Alert.alert("Imposible calificar", err.response.data); + }) + .finally(() => { + setReviewComment(""); + setImages([]); + setDefaultRating(3); + showReviewProduct ? setShowReviewProduct(!showReviewProduct) : setShowReviewSeller(!showReviewSeller); + }); + } else { + let review: TReview = { + id: "", + rating: defaultRating, + description: reviewComment, + base64Images: images!, + date: "", + customerEmail: email, + sellerEmail: sellerEmail, + }; + //showReviewProduct(review); + } }; return ( @@ -146,118 +182,119 @@ export default function GiveReview(props: any) { contentContainerStyle={{ alignItems: "center", justifyContent: "center", flex: 1 }} showsVerticalScrollIndicator={false} > - <View - className="mt-5 bg-[#fff] dark:bg-[#0f0a36] rounded-3xl p-[35px] items-center" - style={{ - shadowColor: "#000", - shadowOffset: { - width: 0, - height: 2, - }, - shadowOpacity: 0.25, - shadowRadius: 4, - elevation: 5, - }} - > - <TouchableOpacity - className="absolute right-[-15px] w-16 h-16 top-3" - onPress={() => { - setImages([]); - setPhotos([]); - setReviewComment(""); - setLoading(false); - setDefaultRating(3); - - showReviewProduct - ? setShowReviewProduct(!showReviewProduct) - : setShowReviewSeller(!showReviewSeller); + <View className="items-center justify-center flex-1 max-h-[750px] "> + <View + className="mt-5 bg-[#fff] dark:bg-[#0f0a36] rounded-3xl p-[35px] items-center" + style={{ + shadowColor: "#000", + shadowOffset: { + width: 0, + height: 2, + }, + shadowOpacity: 0.25, + shadowRadius: 4, + elevation: 5, }} > - <XCircle size={25} weight="regular" color={colorScheme === "dark" ? "white" : "black"} /> - </TouchableOpacity> - <Text className="text-lg font-semibold dark:text-dark-mode-text"> - {showReviewProduct ? "Calificar producto" : "Calificar vendedor"} - </Text> - <Divider - style={dark ? { height: 2, backgroundColor: "white" } : { height: 2, backgroundColor: "#32377B" }} - /> - <View className="w-[300]"> - <TextInput - onChangeText={setReviewComment} - value={reviewComment} - left={ - <TextInput.Icon - name={() => <ChatCircleDots size={18} weight="bold" color={dark ? "white" : "black"} />} - /> - } - placeholder={"Comentario"} - secureTextEntry={false} - style={dark ? myStyle.textAreaB : myStyle.textArea} - keyboardType={undefined} - onBlur={undefined} - onSubmitEditing={undefined} - multiline={true} - theme={dark ? { colors: { placeholder: "white", text: "white" } } : {}} - /> - </View> - <View className="mt-2"> - <CustomRatingBar /> - </View> - {showReviewProduct && ( - <View className="flex-row mt-"> - <CustomButton - onPress={() => { - openPicker(); - setLoading(true); - }} - value={"Imágenes"} - style={undefined} - isDisabled={false} - /> - <View className={"right-8 top-[26]"}> - <ImageSquare size={20} weight="fill" color={"white"} /> - </View> - </View> - )} - {loading ? ( - <Loading text="Subiendo fotos" bg={dark ? true : false} /> - ) : ( - showReviewProduct && - images && - images.length > 0 && ( - <View className="flex-row flex-wrap justify-center"> - <SliderSlick pictures={images!} /> - </View> - ) - )} - - <View className="flex-row justify-between mt-3"> - <CustomButton + <TouchableOpacity + className="absolute right-[-15px] w-16 h-16 top-3" onPress={() => { setImages([]); setPhotos([]); setReviewComment(""); setLoading(false); setDefaultRating(3); + showReviewProduct ? setShowReviewProduct(!showReviewProduct) : setShowReviewSeller(!showReviewSeller); }} - value={"Salir"} - style={{ width: 130, margin: 10 }} - isDisabled={false} + > + <XCircle size={25} weight="regular" color={colorScheme === "dark" ? "white" : "black"} /> + </TouchableOpacity> + <Text className="text-lg font-semibold dark:text-dark-mode-text"> + {showReviewProduct ? "Calificar producto" : "Calificar vendedor"} + </Text> + <Divider + style={dark ? { height: 2, backgroundColor: "white" } : { height: 2, backgroundColor: "#32377B" }} /> - <View className={"right-9 top-[26]"}> - <X size={20} weight="fill" color="white" /> + <View className="w-[300]"> + <TextInput + placeholder="Comentario" + multiline={true} + left={ + <TextInput.Icon + name={() => <ChatCircleDots size={18} weight="bold" color={dark ? "white" : "black"} />} + /> + } + onChangeText={setReviewComment} + onContentSizeChange={(event) => { + setInputHeight(event.nativeEvent.contentSize.height); + }} + theme={dark ? { colors: { placeholder: "white", text: "white" } } : {}} + style={[myStyle.textAreaB, { height: Math.max(50, inputHeight) }]} + value={reviewComment} + /> </View> - <CustomButton - onPress={() => handleReview()} - value={"Calificar"} - style={{ width: 130, margin: 10 }} - isDisabled={false} - /> - <View className={"right-9 top-[26]"}> - <Star size={20} weight="duotone" color="white" /> + <View className="mt-2"> + <CustomRatingBar /> + </View> + {showReviewProduct && ( + <View className="flex-row mt-"> + <CustomButton + onPress={() => { + openPicker(); + setLoading(true); + }} + value={"Imágenes"} + style={undefined} + isDisabled={false} + /> + <View className={"right-8 top-[26]"}> + <ImageSquare size={20} weight="fill" color={"white"} /> + </View> + </View> + )} + {loading ? ( + <Loading text="Subiendo fotos" bg={dark ? true : false} /> + ) : ( + showReviewProduct && + images && + images.length > 0 && ( + <View className="flex-row flex-wrap justify-center"> + <SliderSlick pictures={images!} /> + </View> + ) + )} + + <View className="flex-row justify-between mt-3"> + <CustomButton + onPress={() => { + setImages([]); + setPhotos([]); + setReviewComment(""); + setLoading(false); + setDefaultRating(3); + showReviewProduct + ? setShowReviewProduct(!showReviewProduct) + : setShowReviewSeller(!showReviewSeller); + }} + value={"Salir"} + style={{ width: 130, margin: 10 }} + isDisabled={false} + /> + <View className={"right-9 top-[25]"}> + <X size={20} weight="fill" color="white" /> + </View> + <CustomButton + onPress={() => handleReview()} + value={"Calificar"} + style={{ width: 130, margin: 10 }} + isDisabled={false} + /> + <View className={"right-9 top-[25]"}> + <Star size={20} weight="duotone" color="white" /> + </View> </View> </View> </View> diff --git a/src/screens/customer/Profile.tsx b/src/screens/customer/Profile.tsx index c21e7ae..26273d5 100644 --- a/src/screens/customer/Profile.tsx +++ b/src/screens/customer/Profile.tsx @@ -4,7 +4,7 @@ import { getData, getCustomerProfile, updateProfile } from "../../services/Reque import StarSvg from "../../components/Svgs/StarSvg"; import { useFocusEffect, useNavigation } from "@react-navigation/core"; import CustomButton from "../../components/CustomButton"; -import { AddressBook, BookmarkSimple, Handbag, Star, Swap, TrashSimple, WarningOctagon } from "phosphor-react-native"; +import { AddressBook, Handbag, Star, Swap, TrashSimple, WarningOctagon } from "phosphor-react-native"; import { useColorScheme } from "nativewind"; import { TCustomer } from "../../../urubuy"; import { Menu, MenuTrigger, MenuOptions, MenuOption } from "react-native-popup-menu"; @@ -38,6 +38,7 @@ function Profile() { averageRating: res.data.averageRating, addresses: res.data.addresses, picture: res.data.picture, + givenUserReviews: res.data.givenUserReviews, }; setUser(myUser); } else console.error("getting profile"); @@ -162,7 +163,7 @@ function Profile() { <TouchableOpacity> <CustomButton isDisabled={false} - onPress={() => nav.navigate("Reviews" as never)} + onPress={() => nav.navigate("Reviews" as never, { reviews: user?.givenUserReviews } as never)} value={"Mis calificaciones"} style={undefined} /> diff --git a/src/screens/customer/Purchase.tsx b/src/screens/customer/Purchase.tsx index a3c6059..6ddce89 100644 --- a/src/screens/customer/Purchase.tsx +++ b/src/screens/customer/Purchase.tsx @@ -15,8 +15,8 @@ type Purchase = { }; const myData = [ - { id: 1, date: "20/11/2011", name: "la compra 1", price: "300" }, - { id: 2, date: "21/11/2011", name: "la compra 2", price: "400" }, + { id: 1, date: "20/11/2011", name: "la compra 1", price: "300", seller: "pepitoSeller" }, + { id: 2, date: "21/11/2011", name: "la compra 2", price: "400", seller: "pepitoSeller" }, { id: 3, date: "10/07/2021", name: "3 la compra", price: "100" }, { id: 4, date: "10/10/2010", name: "4 la compra", price: "400" }, { id: 5, date: "11/11/2011", name: "5inho", price: "500" }, @@ -36,11 +36,12 @@ export default function Purchase(props: any) { purchase: any; }; - const handleReviewing = (purchaseId: string) => { + const handleReviewing = (purchaseId: string, seller: string) => { nav.navigate( "ReviewSeller" as never, { id: `${purchaseId}`, + seller: seller, } as never, ); }; @@ -80,7 +81,7 @@ export default function Purchase(props: any) { <CustomButton value={"Calificar"} style={{ width: "40%", margin: 35 }} - onPress={() => handleReviewing(purchase.id)} + onPress={() => handleReviewing(purchase.id, purchase.seller)} isDisabled={false} /> <View diff --git a/src/screens/customer/Review.tsx b/src/screens/customer/Review.tsx index ec6909e..f24ef7f 100644 --- a/src/screens/customer/Review.tsx +++ b/src/screens/customer/Review.tsx @@ -1,9 +1,11 @@ -import { useNavigation } from "@react-navigation/core"; +import { useFocusEffect, useNavigation } from "@react-navigation/core"; import React, { useEffect, useState } from "react"; import { FlatList, ImageBackground, Image, Text, View, TouchableOpacity } from "react-native"; import { Divider } from "react-native-paper"; import StarSvg from "../../components/Svgs/StarSvg"; import { useColorScheme } from "nativewind"; +import { TUserReview } from "../../../urubuy"; +import Loading from "../../components/Loading"; type Review = { id: number; @@ -45,18 +47,28 @@ const myData = [ export default function Review(props: any) { const nav = useNavigation(); - const [reviews, setPurchases] = useState<Review[] | undefined>(undefined); + const [reviews, setReviews] = useState<Review[] | undefined>(undefined); + const [reviewsUser, setReviewsUser] = useState<TUserReview[] | undefined>(undefined); + const { colorScheme } = useColorScheme(); const dark = colorScheme === "dark"; useEffect(() => { - setPurchases(myData); + setReviewsUser(props.route.params.reviews); + }, [props]); + + useEffect(() => { + setReviews(myData); }, []); type ReviewCard = { review: Review; }; + type ReviewUserCard = { + review: TUserReview; + }; + const handleProfileSeller = (seller: string) => { nav.navigate( "UserProfile" as never, @@ -66,21 +78,21 @@ export default function Review(props: any) { ); }; - const Card: React.FC<ReviewCard> = ({ review }) => { + const Card: React.FC<ReviewUserCard> = ({ review }) => { return ( <View className=" ml-[2%] mb-[10px] w-[96%] - min-h-[200px] + min-h-auto bg-[#ffffff] dark:bg-dark-mode-bg border-header-color rounded-[5px] border-[1.33px]" > <View className="flex-row justify-between"> <Text className="text-[18px] p-[11px] items-start dark:text-dark-mode-text font-semibold"> - Fecha: {review.date} + Fecha: {Date.now()} </Text> <View className="flex-row p-2"> {[...Array(review.rating)].map((x, i) => ( @@ -92,7 +104,9 @@ export default function Review(props: any) { </View> <Divider style={dark ? { height: 1.5, backgroundColor: "white" } : { height: 1.5 }} /> <View className="flex-row justify-between"> - <Text className="text-[18px] p-[5px] ml-6 mt-3 dark:text-dark-mode-text font-semibold">{review.name}</Text> + <Text className="text-[18px] p-[5px] ml-6 mt-3 dark:text-dark-mode-text font-semibold"> + {review.description} + </Text> <Text className="text-[18px] p-[5px] mr-6 mt-3 dark:text-dark-mode-text font-semibold"> {review.description} @@ -105,9 +119,9 @@ export default function Review(props: any) { /> <View className="flex-row"> <Text className="text-[18px] p-[11px] dark:text-dark-mode-text font-semibold">Vendedor</Text> - <TouchableOpacity onPress={() => handleProfileSeller(review.seller.email)}> + <TouchableOpacity onPress={() => handleProfileSeller(review.sellerEmail)}> <Text className="text-[18px] p-[11px] text-header-color dark:text-[#f1c533] font-semibold"> - {review.seller.email} + {review.sellerEmail} </Text> </TouchableOpacity> </View> @@ -123,12 +137,22 @@ export default function Review(props: any) { className="w-full h-full bg-no-repeat" blurRadius={6} > - <FlatList - className="mt-2" - data={reviews} - keyExtractor={(item) => String(item.id)} - renderItem={({ item }) => <Card review={item} />} - /> + {reviewsUser ? ( + reviewsUser.length > 0 ? ( + <FlatList + className="mt-2" + data={reviewsUser} + keyExtractor={(item) => String(item.id)} + renderItem={({ item }) => <Card review={item} />} + /> + ) : ( + <Text className="text-[18px] p-[11px] text-header-color dark:text-[#f1c533] font-semibold"> + No hay reviews + </Text> + ) + ) : ( + <Loading text="Cargando..." bg={true} /> + )} </ImageBackground> </> ); diff --git a/src/screens/customer/Settings.tsx b/src/screens/customer/Settings.tsx index 7a067bb..d43afea 100644 --- a/src/screens/customer/Settings.tsx +++ b/src/screens/customer/Settings.tsx @@ -273,7 +273,7 @@ function Settings() { > <View className="items-center justify-center flex-1 max-h-[750px] "> <View - className="mt-5 bg-[#fff] dark:bg-[#292626] rounded-3xl p-[35px] items-center" + className="mt-5 bg-[#fff] dark:bg-[#0f0a36] rounded-3xl p-[35px] items-center" style={{ shadowColor: "#000", shadowOffset: { @@ -340,7 +340,7 @@ function Settings() { > <View className="items-center justify-center flex-1 max-h-[650px] "> <View - className="mt-5 bg-[#fff] dark:bg-[#292626] rounded-3xl p-[35px] items-center" + className="mt-5 bg-[#fff] dark:bg-[#0f0a36] rounded-3xl p-[35px] items-center" style={{ shadowColor: "#000", shadowOffset: { @@ -359,7 +359,7 @@ function Settings() { <XCircle size={25} weight="regular" color={colorScheme === "dark" ? "white" : "black"} /> </TouchableOpacity> <Text className="text-[#f00] text-[19px] font-semibold mx-auto"> - Estas apunto de suspender tu cuenta + Estás apunto de suspender tu cuenta </Text> <Text className="text-[#000] dark:text-dark-mode-text text-[18px] font-semibold mx-auto mt-2"> Esta acción es reversible registrándote nuevamente en la plataforma con el mismo email. Ten en @@ -413,7 +413,7 @@ function Settings() { > <View className="items-center justify-center flex-1 max-h-[650px] "> <View - className="mt-5 bg-[#fff] dark:bg-[#292626] rounded-3xl p-[35px] items-center" + className="mt-5 bg-[#fff] dark:bg-[#0f0a36] rounded-3xl p-[35px] items-center" style={{ shadowColor: "#000", shadowOffset: { diff --git a/src/screens/customer/ShoppingCart.tsx b/src/screens/customer/ShoppingCart.tsx index 6b5b206..e3c2f39 100644 --- a/src/screens/customer/ShoppingCart.tsx +++ b/src/screens/customer/ShoppingCart.tsx @@ -42,7 +42,6 @@ LogBox.ignoreAllLogs(); // workaround para el warning en el device de cannot upd export async function deleteUserCart(nav: any) { await deleteShoppingCart(); - await removeData("myCart"); await removeData("cartId"); nav.navigate("Home" as never); } @@ -247,7 +246,13 @@ export default function ShoppingCart() { s?.findIndex((x) => x.idShoppingPost === +postId), 1, ); - getCart(); + getUserCart().then((res: any) => { + if (res.status === 200) { + let arr: string[] = getKeys(res.data.shoppingPosts)!; + if (arr.length === 0) deleteUserCart(nav); + else getCart(); + } + }); } }); } @@ -287,21 +292,7 @@ export default function ShoppingCart() { } }) .catch(async (err) => { - // esto ya iria - let c = await getData("hasCheckout"); - if (c) { - findCheckoutById(c).then((res: any) => { - if (res.status === 200) { - checkout = res.data; - nav.navigate( - "Checkout" as never, - { - checkout: checkout, - } as never, - ); - } else console.log("no hay checkout"); - }); - } + console.log(err.response.data); }); } }; @@ -314,7 +305,6 @@ export default function ShoppingCart() { if (address) { let posts = shoppingCart?.shoppingPosts; let hasDelivery = isDelivery(address); - // await getSellers(getKeys(posts)); Object.entries(posts!).forEach(([key, value]) => { if (key === productId) { let p: TCheckout = { @@ -323,11 +313,10 @@ export default function ShoppingCart() { isDelivery: hasDelivery, address: address, }; - // handleSameSeller(checkoutProducts!); - if (checkoutProducts?.find((x) => x.shoppingPostId === +productId) === undefined) + if (checkoutProducts?.find((x) => x.shoppingPostId === +productId) === undefined) { setCheckoutProducts((prevState) => [...prevState!, p]); - else { + } else { // actualizar address almacenada let cp: TCheckout[] = checkoutProducts!; if (cp) { @@ -338,32 +327,50 @@ export default function ShoppingCart() { x.isDelivery = hasDelivery; } }); - //handleSameSeller(cp); setCheckoutProducts(cp); - } else console.log("no hay checkoutProducts"); + } } + // tengo otro producto del mismo seller? le seteo la misma dirección elegida. + handleSameSeller(address, hasDelivery, productId); + getCart(); // updating ui } }); - getCart(); // updating ui } } - /* - const handleSameSeller = (cp: TCheckout[]) => { - let posts = cp.map((x) => x.shoppingPostId); - let sellers: string[] = []; - console.log(posts); - if (posts.length > 1) { - posts.forEach((x) => { - getShoppingPostById(x).then((res) => { - if (res.status === 200) { - let p: TShoppingPost = res.data; - sellers.push(p.sellerEmail); + + const handleSameSeller = (address: string, hasDelivery: boolean, productId: string) => { + let posts = shoppingPost; + + if (posts?.length! > 1) { + let seller = posts?.find((x) => x.id === productId)?.sellerEmail; + console.log(seller); + let cp: TCheckout[] = checkoutProducts!; + posts?.forEach((x) => { + if (x.id !== productId) { + if (x.sellerEmail === seller) { + if (cp?.find((y) => y.shoppingPostId === +x.id) === undefined) { + let p: TCheckout = { + shoppingPostId: +x.id, + quantity: +handleQuantity(x.id)!, + isDelivery: hasDelivery, + address: address, + }; + setCheckoutProducts((prev) => [...prev!, p]); + } else { + cp.forEach((y) => { + if (y.shoppingPostId === +x.id) { + y.address = address; + y.quantity = +handleQuantity(x.id)!; + y.isDelivery = hasDelivery; + } + }); + setCheckoutProducts(cp); + } } - }); + } }); - console.log(sellers); } - };*/ + }; const handleSelectedValue = (productId: string) => { let c = checkoutProducts?.find((x) => x.shoppingPostId === +productId); @@ -411,6 +418,15 @@ export default function ShoppingCart() { getCart(); }; + const handlePress = (id: any) => { + nav.navigate( + "ShoppingPost" as never, + { + id: id, + } as never, + ); + }; + const Card: React.FC<CardCart> = ({ product }) => { return ( <> @@ -425,9 +441,11 @@ export default function ShoppingCart() { border-header-color rounded-[5px] border-2" style={myStyle.cardCart} > - <Text className="text-[18px] p-[11px] font-semibold dark:text-dark-mode-text text-center"> - {product.title.length > 100 ? product.title.slice(0, 50) : product.title} - </Text> + <TouchableOpacity onPress={() => handlePress(product.id)}> + <Text className="text-[18px] p-[11px] font-semibold dark:text-dark-mode-text text-center"> + {product.title.length > 100 ? product.title.slice(0, 50) : product.title} + </Text> + </TouchableOpacity> <Divider style={ dark @@ -485,19 +503,38 @@ export default function ShoppingCart() { resizeMode="contain" /> + {/* elegir direccion */} + {(showPicker!.length === 0 && loadShow()) || showPicker?.map((sp, index) => sp.idShoppingPost === +product.id ? ( !sp.show ? ( - <TouchableOpacity - key={index} - className="absolute right-10" - onPress={() => handleShowPicker(+product.id)} - > - <Text className="text-[21px] my-auto mx-auto text-[#46d6d6] font-semibold underline"> - Elegir dirección - </Text> - </TouchableOpacity> + checkoutProducts?.length! > 0 && + checkoutProducts?.find( + (x) => + x.shoppingPostId === +product.id && + (x.address === undefined || x.address === null || x.address !== "") !== undefined, + ) ? ( + <TouchableOpacity + key={index} + className="absolute right-10" + onPress={() => handleShowPicker(+product.id)} + > + <Text className="text-[21px] my-auto mx-auto text-[#db8e36] font-semibold underline"> + Cambiar dirección + </Text> + </TouchableOpacity> + ) : ( + <TouchableOpacity + key={index} + className="absolute right-10" + onPress={() => handleShowPicker(+product.id)} + > + <Text className="text-[21px] my-auto mx-auto text-[#46d6d6] font-semibold underline"> + Elegir dirección + </Text> + </TouchableOpacity> + ) ) : ( <View key={index}> <Picker diff --git a/src/services/Requests.tsx b/src/services/Requests.tsx index 1f5e358..0168787 100644 --- a/src/services/Requests.tsx +++ b/src/services/Requests.tsx @@ -1,7 +1,7 @@ import AsyncStorage from "@react-native-async-storage/async-storage"; import axios from "axios"; import Constants from "expo-constants"; -import { TCustomer, TCheckout, TUserKC } from "../../urubuy"; +import { TCustomer, TCheckout, TUserKC, TReview, TUserReview } from "../../urubuy"; const iLocal = axios.create({ baseURL: Constants.manifest?.extra?.URL_LOCAL, // ultra relativo cada pc tiene la suya localhost no funca :/ @@ -321,6 +321,11 @@ export const suspendAccount = async (email: string) => { } }; +export const reviewSeller = async (review: TUserReview) => { + //console.log(review); + return iLocal.post("userReview/add", review); +}; + // operaciones para localstorage export const storeData = async (key: string, value: string) => { diff --git a/urubuy.d.ts b/urubuy.d.ts index ead2585..c0984e8 100644 --- a/urubuy.d.ts +++ b/urubuy.d.ts @@ -58,6 +58,8 @@ export type TCustomer = { picture: string; addresses: string[]; averageRating: number; + givenUserReviews?: TUserReview[]; + receivedUserReviews?: TUserReview[]; }; export type TSeller = { @@ -114,10 +116,22 @@ export type TCheckoutShoppingPost = { address: string; }; +export type TUserReview = { + id: string; + rating: number; + description: string; + date: string; + customerEmail: string; + sellerEmail: string; + from: "CUSTOMER"; +}; + export type TReview = { id: string; rating: number; description: string; base64Images: string[]; date: string; + customerEmail: string; + sellerEmail: string; }; -- GitLab From e83c5c64a74a4ca794b42f5ee338acaafc930bdc Mon Sep 17 00:00:00 2001 From: "mathias.fernandez.bo" <mathias.fernandez.bo@fing.edu.uy> Date: Fri, 2 Dec 2022 16:01:53 -0300 Subject: [PATCH 2/6] mejoras screen reviews con api --- app.json | 2 +- assets/star_corner.png | Bin 1595 -> 0 bytes assets/star_filled.png | Bin 1043 -> 0 bytes assets/styles.tsx | 3 - package-lock.json | 1335 +++++++++++++++--------- package.json | 3 + src/components/CustomButton.tsx | 2 +- src/components/Navigation/SideMenu.tsx | 8 +- src/screens/Home.tsx | 108 +- src/screens/Login.tsx | 2 + src/screens/ShoppingPost.tsx | 47 +- src/screens/SignUp.tsx | 5 +- src/screens/UserProfile.tsx | 131 ++- src/screens/customer/Checkout.tsx | 2 +- src/screens/customer/GiveReview.tsx | 131 ++- src/screens/customer/Help.tsx | 2 +- src/screens/customer/Profile.tsx | 213 ++-- src/screens/customer/Purchase.tsx | 92 +- src/screens/customer/Review.tsx | 262 +++-- src/screens/customer/Settings.tsx | 2 +- src/screens/customer/ShoppingCart.tsx | 9 +- src/services/Requests.tsx | 4 +- tailwind.config.js | 1 + urubuy.d.ts | 15 + 24 files changed, 1546 insertions(+), 833 deletions(-) delete mode 100644 assets/star_corner.png delete mode 100644 assets/star_filled.png diff --git a/app.json b/app.json index 321b4e0..62dca2d 100644 --- a/app.json +++ b/app.json @@ -9,7 +9,7 @@ "CLIENT_SECRET": "eiqRw4HaFHFzxADC8lz8xdiZ9LqJz4wj", "URL_LOCAL": "http://192.168.1.13:5000/", "PAYPAL": "http://192.168.1.13:5000/paypal/pay/", - "URL_CLOUD": "https://backend.uru-buy.me/", + "URL_CLOUD": "http://backend.uru-buy.me/", "URL_KC": "http://urubuy.ddns.net:8080/realms/Urubuy/protocol/openid-connect", "URL_KC_ADMIN": "http://urubuy.ddns.net:8080/admin/realms/Urubuy", "DEVICE_ID": "RNExpo" diff --git a/assets/star_corner.png b/assets/star_corner.png deleted file mode 100644 index cb22428ff312db101932f28e8fbf7a78f7503804..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1595 zcmX|B2{=`07{16dmZ^!c4oVZ((}*&WF(lc}UF_O$yF64#O13P6Yndz&S+a&vq-4pO zErq1JSh5TWm5{rfdxdMMJO8<NW}fFi-~XNO|GxKqzwbZKNwT-KmXTDJM4?bJkd1{S z*v*hfLIl{N=2$ukCA4IZbG8JpFc}Y1uq-NuMTJ;2V3EZn3mk~akMO$8==>a*2EqIU z9$B9=h+*=5kk1=+fyoe)g5e`TyeSAC!Xr>L43mNdB_H}+m}Gv0ih-#J-6t}hK8OPj zj8H(pSsb!r3?cY@Sdat#j}K0lCv2HCEDN9k76C5}!{ebC$SXpDK>e!+$$=@*ml0b* zQ%owv28FM&yeby~7mEUfL3A>nGh`z`g9i}}EE-}#`7+rWQ9{A43|WB)=amB=${zTP zenAefh%?h=20B7||4$g8194;_ELboE#-KIO10p<L3{Z<4fk}dP1f)nZ4vd;j!@>Mo zpp65@CAbb6m=Xk_7zhGbSpLK?E5Jw8Vwrr+i~&TaKm&-dM}dADgq?~3w;Zve83wk} zAV*s#)M5SYI=$+*I^R4WyxXDu)%)I@sOH784`TcLis!}mZUy8oe5bY<n6o6Q!VS(` zmilQu%=X%yj`s{1?3L`NGejX9|K^SH`qT^N3MJDm)*2#R>`pvd>*Jc0y8Yxyr7<`8 zVOh$qSKs%9M8!!oCf8(C`3#hfMA#iTwJJ;^KMp$N&eBcVUom@0F71<9EaxbF#cT1$ z^mf+*)wYIb#=B3L^yS8b4^@N+SsZr`n{3S8aB_4|OthO$uKki@1Nl^1sAS%8^gZL- zfXVTG*yNLvos(DXd$Os8wRMsfJ-J7Z6u$GVUq=^Q#41`)x?{XR-SaJUtlCwji{LO; z1Jw!{JW806sC7`JY2q{ulokvNAe(3Hf7cSFTxDgO>wD36%j@ws{3{_b(J81&!UH<r zcF5GSSDD*Tc3*Kfop`}_RzFzFI2ATXaPRg}NT$RP4SklnwM}kLZ*G``9DaUHY|Z4U zXr7nR^C$aKa2?wOt*so}tt-q??Fm|J9JV4(e4-}(*hdXxPT|evTL)tcUKnL86uxL# zg^S(NECSMQEhqhnvm1E5u4Z!neu>^w^e@jM>6M1ZbhV>`hcg|6wk_CDHnFgxr@k<7 zcWQV&w})LOhiyUEW#_co708*hi;N<e+X*S2mInz(qnUIi^-}cx5oW!kYZ6+koqaAa z*Tt<<qr5e+wTv9~s%96awKD$Uc>9LSxKlz}IiY4?ozNzk{k{)>d0IX(a7*4WK*9st z=i(Kw8<=rPN;-6#TeZ3}YPuat`l~{0%e`aU-S|i`JohdtOMH_nF1gOqQB@x+(_EaB zb@o-aI`~=5qp6SPO8LDig<$fBuo9c21b<|6=10QA<kfl7pYJ|)TX25962@Jy&wFxq z4xOk_x1nH9Ki%PbF+R7Bn>#pBa@~?}{B~gg=~Sj)E>}6<J5s;hHjA)s*wDWz|E?#@ zqkX>U(H}2ejRLN62xDC@eKI6XWAI~BvvJOFhFx`i=c=swJ(9s>!mo@5Xp5HhT68`# zXYEK(zo_b){?B6Bj;$qfjmI6Mh0@(-V|6n(56qM)6zS*`4HX1LW=nKBsbAk_k4S&I zdrTvAH8NL1nQaw0g)`=UCDKy4?gZuiq;o+DFPX(|i~dcg^CR{)R~Wam-sc*elZYxc z^x~o9yo`mP>}x}bZJr3|HbuXYlQv)17(TS)g}>0xm3}ITrD>M#hSI*0R*EujZTys5 z!uvD|>eLj<&xjaa&H4e~eN?tAczDO!gQfZDFIlR%+tr?=tN3nd{PjkMotJx0R8#ys zt(<Q4qV%R7jD}K$MZA1ggHhL3%riHPVt%_B(rq1)a3do*BvR_Ecd$#+jl9g6=x<9i aTV2k3l=9QZzrx_hfPyS-EgqW_N&f($*k)4z diff --git a/assets/star_filled.png b/assets/star_filled.png deleted file mode 100644 index f37d645f7075b0fd479deb23bca6e4b3f66a5deb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1043 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+yeRz!)6h6XN<G1Q`DRZ}`6|^#6W` z|7VQ<Uk&|#+w=Z@hsVc4pPli2b=BeZ4Zlw(13v-Tr@UUD^Lul_=j}z$x2N3Ro$>u} z(f7k??~mtwK3(v7bH?}WInTEj+}~aFet+KU!#S^yXT08?^Lcm1<K0>B_vgIcpY!~1 z*7L&!&yQ!l-<|h<ch>9udC&J}eLeu$=YYuT9gquD2GZ;O0Z5+p{&3a{sO;TYPoUs? zpn8}gKsL~Ph+>c-=fGNEB0!^H=D?Lf901}15y)zYnsZQb7#C^<*g&`%u&aRTLAns; zplX3D_ByFEUmh6B1tmd#!3>N{%q*;I>>Qk2JiNjp5>nDKvT}+_s%jcq+Bya%=9V_L zcJ@wg?%qBDfuRwR(Xk21DQW51Ir)V}#bpicy?y-?r%j(dZ^fp~+qUmMeBtV~>o;!R zx_#%~{RfYqJbm{3<?A=^K79K8_1pI!KY#uH^Y<S=_wN8;)c*H$aSW-rwe|YbFs(p_ zwuk;sfp3l+2s@(p<{g7!V1VPs$?yNw&wZ*RcA7Em{mio;cXoY08ehCSaK=(qktI44 zHJla2POyqBF!4L)y)ds&<@tg&Puf)Sy%uD(&63p6>I)RsZkxq$nJM5=kCE=HmM+aS zAIHYWlO(6}MVKFqS4)`rw`qUOjl`=KrN<H{zMW#V+$_TQl+NM}N5s;mZQu>#F+OhK zQ@oW=&iMGpgw@<ae*N`z#u9&*HNMX%D8Bc;P^o?IMf2T-5<eGd#!o!l8yUY?cGkQD zukM|+7Tq)d&04l9gD(e}YIqp`nQK*lW^Q=j+7(xG;frnX$zu6SyXLQWuu@ubF8`J{ z3x)S@QO^wABx`lgI;!Zo>$Ghwx*l5;-9PL4?#^|S^EI3$lI;}78#qfSx1sSDhi}J~ z!vSX{m!8W~2oPQ7vV+U1bjph68PkR0I(h?>c#^cIL^R&8Q~jn`=Gv*vu`_sz$4<pd zjw|^(e1fuslwMDXYWJ8B<k)dUQ?%WIb+ZgFkBp%=YtPr9=QT?>G^8w-`>i)Qe|g<< z*$WoS)~}p+{I{6#JMq{P1-kc)lev#M`BcZ~wfp`2q<q=QVA_&rrE7&OwXVml^gI+` zT3?fQU1|NTxBmZDv`ws=v@({Tr?M<q<+tnfiU+L|zB`mmvR<g?QQBITu!MElmOt0` a{%4Q-eWSlsbRj6SGkCiCxvX<aXaWGb{~lQY diff --git a/assets/styles.tsx b/assets/styles.tsx index e2855ae..18e8e57 100644 --- a/assets/styles.tsx +++ b/assets/styles.tsx @@ -73,13 +73,10 @@ export default StyleSheet.create({ textAlign: "center", backgroundColor: "#504e4e", color: "purple", - height: 100, }, - textArea: { marginTop: 5, justifyContent: "center", - height: 100, textAlign: "center", backgroundColor: "white", color: "purple", diff --git a/package-lock.json b/package-lock.json index f7c23a5..a7e7757 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,13 +34,16 @@ "react-native-dynamic-search-bar": "github:WrathChaos/react-native-dynamic-search-bar#expo", "react-native-gesture-handler": "~2.5.0", "react-native-keyboard-aware-scroll-view": "^0.9.5", + "react-native-pager-view": "5.4.24", "react-native-paper": "^4.12.5", "react-native-popup-menu": "^0.16.1", "react-native-reanimated": "^2.12.0", "react-native-safe-area-context": "4.3.1", "react-native-screens": "~3.15.0", "react-native-slick": "^1.6.0", + "react-native-star-rating-widget": "^1.5.0", "react-native-svg": "12.3.0", + "react-native-tab-view": "^3.3.2", "react-native-web": "~0.18.7", "react-native-webview": "11.23.0", "react-navigation": "^4.4.4" @@ -79,28 +82,28 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.1.tgz", - "integrity": "sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz", + "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.2.tgz", - "integrity": "sha512-w7DbG8DtMrJcFOi4VrLm+8QM4az8Mo+PuLBKLp2zrYRCow8W/f9xiXm5sN53C8HksCyDQwCKha9JiDoIyPjT2g==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.5.tgz", + "integrity": "sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==", "dependencies": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.2", + "@babel/generator": "^7.20.5", "@babel/helper-compilation-targets": "^7.20.0", "@babel/helper-module-transforms": "^7.20.2", - "@babel/helpers": "^7.20.1", - "@babel/parser": "^7.20.2", + "@babel/helpers": "^7.20.5", + "@babel/parser": "^7.20.5", "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.2", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -116,11 +119,11 @@ } }, "node_modules/@babel/generator": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.2.tgz", - "integrity": "sha512-SD75PMIK6i9H8G/tfGvB4KKl4Nw6Ssos9nGgYwxbgyTP0iX/Z55DveoH86rmUB/YHTQQ+ZC0F7xxaY8l2OF44Q==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.5.tgz", + "integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==", "dependencies": { - "@babel/types": "^7.20.2", + "@babel/types": "^7.20.5", "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, @@ -182,9 +185,9 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.2.tgz", - "integrity": "sha512-k22GoYRAHPYr9I+Gvy2ZQlAe5mGy8BqWst2wRt8cwIufWTxrsVshhIBvYNqC80N0GSFWTsqRVexOtfzlgOEDvA==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.5.tgz", + "integrity": "sha512-3RCdA/EmEaikrhayahwToF0fpweU/8o2p8vhc1c/1kftHOdTKuC65kik/TLc+qfbS8JKw4qqJbne4ovICDhmww==", "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-environment-visitor": "^7.18.9", @@ -202,12 +205,12 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz", - "integrity": "sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.20.5.tgz", + "integrity": "sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==", "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.1.0" + "regexpu-core": "^5.2.1" }, "engines": { "node": ">=6.9.0" @@ -423,27 +426,27 @@ } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz", - "integrity": "sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz", + "integrity": "sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==", "dependencies": { "@babel/helper-function-name": "^7.19.0", "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.1.tgz", - "integrity": "sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg==", + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz", + "integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==", "dependencies": { "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.0" + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5" }, "engines": { "node": ">=6.9.0" @@ -463,9 +466,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.2.tgz", - "integrity": "sha512-afk318kh2uKbo7BEj2QtEi8HVCGrwHUffrYDy7dgVcSa2j9lY3LDjPzcyGdpX7xgm35aWqvciZJ4WKmdF/SxYg==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz", + "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==", "bin": { "parser": "bin/babel-parser.js" }, @@ -552,11 +555,11 @@ } }, "node_modules/@babel/plugin-proposal-decorators": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.20.2.tgz", - "integrity": "sha512-nkBH96IBmgKnbHQ5gXFrcmez+Z9S2EIDKDQGp005ROqBigc88Tky4rzCnlP/lnlj245dCEQl4/YyV0V1kYh5dw==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.20.5.tgz", + "integrity": "sha512-Lac7PpRJXcC3s9cKsBfl+uc+DYXU5FD06BrTFunQO6QIQT+DwyzDPURAowI3bcvD1dZF/ank1Z5rstUJn3Hn4Q==", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.20.2", + "@babel/helper-create-class-features-plugin": "^7.20.5", "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-replace-supers": "^7.19.1", "@babel/helper-split-export-declaration": "^7.18.6", @@ -739,13 +742,13 @@ } }, "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz", - "integrity": "sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.20.5.tgz", + "integrity": "sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ==", "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.20.5", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, "engines": { @@ -1062,9 +1065,9 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.2.tgz", - "integrity": "sha512-y5V15+04ry69OV2wULmwhEA6jwSWXO1TwAtIwiPXcvHcoOQUqpyMVd2bDsQJMW8AurjulIyUV8kDqtjSwHy1uQ==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.5.tgz", + "integrity": "sha512-WvpEIW9Cbj9ApF3yJCjIEEf1EiNJLtXagOrL5LNWEZOo3jv8pmPoYTSNJQvqej8OavVlgOoOPw6/htGZro6IkA==", "dependencies": { "@babel/helper-plugin-utils": "^7.20.2" }, @@ -1306,12 +1309,12 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz", - "integrity": "sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz", + "integrity": "sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.19.0", - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-create-regexp-features-plugin": "^7.20.5", + "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { "node": ">=6.9.0" @@ -1364,11 +1367,11 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.1.tgz", - "integrity": "sha512-nDvKLrAvl+kf6BOy1UJ3MGwzzfTMgppxwiD2Jb4LO3xjYyZq30oQzDNJbCQpMdG9+j2IXHoiMrw5Cm/L6ZoxXQ==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.5.tgz", + "integrity": "sha512-h7plkOmcndIUWXZFLgpbrh2+fXAi47zcUX7IrOQuZdLD0I0KvjJ6cvo3BEcAOsDOcZhVKGJqv07mkSqK0y2isQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { "node": ">=6.9.0" @@ -1452,12 +1455,12 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz", - "integrity": "sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz", + "integrity": "sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "regenerator-transform": "^0.15.0" + "@babel/helper-plugin-utils": "^7.20.2", + "regenerator-transform": "^0.15.1" }, "engines": { "node": ">=6.9.0" @@ -1769,11 +1772,11 @@ } }, "node_modules/@babel/runtime": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.1.tgz", - "integrity": "sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==", + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.6.tgz", + "integrity": "sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==", "dependencies": { - "regenerator-runtime": "^0.13.10" + "regenerator-runtime": "^0.13.11" }, "engines": { "node": ">=6.9.0" @@ -1793,18 +1796,18 @@ } }, "node_modules/@babel/traverse": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.1.tgz", - "integrity": "sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.5.tgz", + "integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==", "dependencies": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.1", + "@babel/generator": "^7.20.5", "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-function-name": "^7.19.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.1", - "@babel/types": "^7.20.0", + "@babel/parser": "^7.20.5", + "@babel/types": "^7.20.5", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -1813,9 +1816,9 @@ } }, "node_modules/@babel/types": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.2.tgz", - "integrity": "sha512-FnnvsNWgZCr232sqtXggapvlkk/tuwR/qhGzcmxI0GXLCjmPYQPzio2FbdlWuY6y1sHFfQKk+rRbUZ9VStQMog==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz", + "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==", "dependencies": { "@babel/helper-string-parser": "^7.19.4", "@babel/helper-validator-identifier": "^7.19.1", @@ -2036,13 +2039,13 @@ } }, "node_modules/@expo/config": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@expo/config/-/config-7.0.1.tgz", - "integrity": "sha512-4lu0wr45XXJ2MXiLAm2+fmOyy/jjqF3NuDm92fO6nuulRzEEvTP4w3vsibJ690rT81ohtvhpruKhkRs0wSjKWA==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@expo/config/-/config-7.0.3.tgz", + "integrity": "sha512-joVtB5o+NF40Tmsdp65UzryRtbnCuMbXkVO4wJnNJO4aaK0EYLdHCYSewORVqNcDfGN0LphQr8VTG2npbd9CJA==", "dependencies": { "@babel/code-frame": "~7.10.4", - "@expo/config-plugins": "~5.0.1", - "@expo/config-types": "^46.0.1", + "@expo/config-plugins": "~5.0.3", + "@expo/config-types": "^47.0.0", "@expo/json-file": "8.2.36", "getenv": "^1.0.0", "glob": "7.1.6", @@ -2054,11 +2057,11 @@ } }, "node_modules/@expo/config-plugins": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-5.0.1.tgz", - "integrity": "sha512-1OfnsOrfeSkB0VZfT01UjQ5Uq6p+yYbq8yNkj0e99K/6NLHpyvIxj+5tZIV0nQXgkOcqBIABL2uA7lwB8CkaBQ==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-5.0.4.tgz", + "integrity": "sha512-vzUcVpqOMs3h+hyRdhGwk+eGIOhXa5xYdd92yO17RMNHav3v/+ekMbs7XA2c3lepMO8Yd4/5hqmRw9ZTL6jGzg==", "dependencies": { - "@expo/config-types": "^46.0.0", + "@expo/config-types": "^47.0.0", "@expo/json-file": "8.2.36", "@expo/plist": "0.0.18", "@expo/sdk-runtime-versions": "^1.0.0", @@ -2154,9 +2157,9 @@ } }, "node_modules/@expo/config-types": { - "version": "46.0.2", - "resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-46.0.2.tgz", - "integrity": "sha512-PXkmOgNwRyBfgVT1HmFZhfh3Qm7WKKyV6mk3/5HJ/LzPh1t+Zs2JrWX8U2YncTLV1QzV7nV8tnkyvszzqnZEzQ==" + "version": "47.0.0", + "resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-47.0.0.tgz", + "integrity": "sha512-r0pWfuhkv7KIcXMUiNACJmJKKwlTBGMw9VZHNdppS8/0Nve8HZMTkNRFQzTHW1uH3pBj8jEXpyw/2vSWDHex9g==" }, "node_modules/@expo/config/node_modules/@babel/code-frame": { "version": "7.10.4", @@ -2241,17 +2244,20 @@ } }, "node_modules/@expo/dev-server": { - "version": "0.1.120", - "resolved": "https://registry.npmjs.org/@expo/dev-server/-/dev-server-0.1.120.tgz", - "integrity": "sha512-x5/jCv0EOpz6FyehXpI5bgDQTVsGZYvgISkAw7n60RhtG+aid6N2CCR9SDMCH70XaUpFnfTW9qvderpCEj7Puw==", + "version": "0.1.123", + "resolved": "https://registry.npmjs.org/@expo/dev-server/-/dev-server-0.1.123.tgz", + "integrity": "sha512-N6UVzzeemfX0AONUSWInvkAAbqon8hRXpyYE/nMPaC6TvAmgGY5ILZAGoXwlpxwY2VKNT0Lx4s/UJ53ytIaHbA==", "dependencies": { "@expo/bunyan": "4.0.0", - "@expo/metro-config": "~0.4.0", + "@expo/metro-config": "~0.5.1", "@expo/osascript": "2.0.33", + "@expo/spawn-async": "^1.5.0", "body-parser": "1.19.0", "chalk": "^4.0.0", "connect": "^3.7.0", "fs-extra": "9.0.0", + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1", "node-fetch": "^2.6.0", "open": "^8.3.0", "resolve-from": "^5.0.0", @@ -2260,6 +2266,21 @@ "temp-dir": "^2.0.0" } }, + "node_modules/@expo/dev-server/node_modules/@expo/metro-config": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-0.5.1.tgz", + "integrity": "sha512-Rvy4ZFgKNDfXO401z2OQF8fWbPj1lLVDL4GF1aqCIhCDHCKrezbwB0xejpcUyndJRCxBL2BMAM+P24t6cKv9Fw==", + "dependencies": { + "@expo/config": "~7.0.2", + "@expo/json-file": "8.2.36", + "chalk": "^4.1.0", + "debug": "^4.3.2", + "find-yarn-workspace-root": "~2.0.0", + "getenv": "^1.0.0", + "resolve-from": "^5.0.0", + "sucrase": "^3.20.0" + } + }, "node_modules/@expo/dev-server/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -2377,9 +2398,9 @@ } }, "node_modules/@expo/devcert": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@expo/devcert/-/devcert-1.0.0.tgz", - "integrity": "sha512-cahGyQCmpZmHpn2U04NR9KwsOIZy7Rhsw8Fg4q+A6563lIJxbkrgPnxq/O3NQAh3ohEvOXOOnoFx0b4yycCkpQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@expo/devcert/-/devcert-1.1.0.tgz", + "integrity": "sha512-ghUVhNJQOCTdQckSGTHctNp/0jzvVoMMkVh+6SHn+TZj8sU15U/npXIDt8NtQp0HedlPaCgkVdMu8Sacne0aEA==", "dependencies": { "application-config-path": "^0.1.0", "command-exists": "^1.2.4", @@ -2393,7 +2414,7 @@ "rimraf": "^2.6.2", "sudo-prompt": "^8.2.0", "tmp": "^0.0.33", - "tslib": "^1.10.0" + "tslib": "^2.4.0" } }, "node_modules/@expo/devcert/node_modules/debug": { @@ -2405,9 +2426,9 @@ } }, "node_modules/@expo/image-utils": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.3.20.tgz", - "integrity": "sha512-NgF/80XENyCS+amwC0P6uk1fauEtUq7gijD19jvl2xknJaADq8M2dMCRHwWMVOXosr2v46f3Z++G/NjmyOVS7A==", + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.3.22.tgz", + "integrity": "sha512-uzq+RERAtkWypOFOLssFnXXqEqKjNj9eXN7e97d/EXUAojNcLDoXc0sL+F5B1I4qtlsnhX01kcpoIBBZD8wZNQ==", "dependencies": { "@expo/spawn-async": "1.5.0", "chalk": "^4.0.0", @@ -2630,6 +2651,37 @@ "sucrase": "^3.20.0" } }, + "node_modules/@expo/metro-config/node_modules/@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, + "node_modules/@expo/metro-config/node_modules/@expo/config": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@expo/config/-/config-7.0.1.tgz", + "integrity": "sha512-4lu0wr45XXJ2MXiLAm2+fmOyy/jjqF3NuDm92fO6nuulRzEEvTP4w3vsibJ690rT81ohtvhpruKhkRs0wSjKWA==", + "dependencies": { + "@babel/code-frame": "~7.10.4", + "@expo/config-plugins": "~5.0.1", + "@expo/config-types": "^46.0.1", + "@expo/json-file": "8.2.36", + "getenv": "^1.0.0", + "glob": "7.1.6", + "require-from-string": "^2.0.2", + "resolve-from": "^5.0.0", + "semver": "7.3.2", + "slugify": "^1.3.4", + "sucrase": "^3.20.0" + } + }, + "node_modules/@expo/metro-config/node_modules/@expo/config-types": { + "version": "46.0.2", + "resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-46.0.2.tgz", + "integrity": "sha512-PXkmOgNwRyBfgVT1HmFZhfh3Qm7WKKyV6mk3/5HJ/LzPh1t+Zs2JrWX8U2YncTLV1QzV7nV8tnkyvszzqnZEzQ==" + }, "node_modules/@expo/metro-config/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -2683,6 +2735,17 @@ "node": ">=8" } }, + "node_modules/@expo/metro-config/node_modules/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@expo/metro-config/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -2707,9 +2770,9 @@ } }, "node_modules/@expo/package-manager": { - "version": "0.0.56", - "resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-0.0.56.tgz", - "integrity": "sha512-PGk34uz4XDyhoNIlPh2D+BDsiXYuW2jXavTiax8d32uvHlRO6FN0cAsqlWD6fx3H2hRn8cU/leTuc4M7pYovCQ==", + "version": "0.0.57", + "resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-0.0.57.tgz", + "integrity": "sha512-Y4RpSL9EqaPF+Vd2GrK6r7Xx7Dv0Xdq3AGAD9C0KwV21WqP/scj/dpjxFY+ABwmdhNsFzYXb8fmDyh4tiKenPQ==", "dependencies": { "@expo/json-file": "8.2.36", "@expo/spawn-async": "^1.5.0", @@ -2817,14 +2880,14 @@ } }, "node_modules/@expo/prebuild-config": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-5.0.3.tgz", - "integrity": "sha512-G4j1H3WFjRaiQ+FgFNULrnIm7RsQyjc4xp6lLTP2ydBv79wO3x8wAdeZvaZh7eOkfu9BESpQzACT1uuJTag5jg==", - "dependencies": { - "@expo/config": "7.0.1", - "@expo/config-plugins": "~5.0.1", - "@expo/config-types": "^46.0.0", - "@expo/image-utils": "0.3.20", + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-5.0.7.tgz", + "integrity": "sha512-D+TBpJUHe4+oTGFPb4o0rrw/h1xxc6wF+abJnbDHUkhnaeiHkE2O3ByS7FdiZ2FT36t0OKqeSKG/xFwWT3m1Ew==", + "dependencies": { + "@expo/config": "~7.0.2", + "@expo/config-plugins": "~5.0.3", + "@expo/config-types": "^47.0.0", + "@expo/image-utils": "0.3.22", "@expo/json-file": "8.2.36", "debug": "^4.3.1", "fs-extra": "^9.0.0", @@ -3388,14 +3451,14 @@ } }, "node_modules/@react-native-async-storage/async-storage": { - "version": "1.17.10", - "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.17.10.tgz", - "integrity": "sha512-KrR021BmBLsA0TT1AAsfH16bHYy0MSbhdAeBAqpriak3GS1T2alFcdTUvn13p0ZW6FKRD6Bd3ryU2zhU/IYYJQ==", + "version": "1.17.11", + "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.17.11.tgz", + "integrity": "sha512-bzs45n5HNcDq6mxXnSsOHysZWn1SbbebNxldBXCQs8dSvF8Aor9KCdpm+TpnnGweK3R6diqsT8lFhX77VX0NFw==", "dependencies": { "merge-options": "^3.0.4" }, "peerDependencies": { - "react-native": "^0.0.0-0 || 0.60 - 0.70 || 1000.0.0" + "react-native": "^0.0.0-0 || 0.60 - 0.71 || 1000.0.0" } }, "node_modules/@react-native-community/cli": { @@ -4518,11 +4581,11 @@ "integrity": "sha512-K0aGNn1TjalKj+65D7ycc1//H9roAQ51GJVk5ZJQFb2teECGmzd86bYDC0aYdbRf7gtovescq4Zt6FR0tgXiHQ==" }, "node_modules/@react-navigation/bottom-tabs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-6.4.0.tgz", - "integrity": "sha512-90CapiXjiWudbCiki9e6fOr/CECQRguIxv5OD7IBfbAMGX5GGiJpX8aqiHAz2DxpAz31v4JZcUr945+lFhXBfA==", + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-6.4.3.tgz", + "integrity": "sha512-nkuHJ31mEyrZZPswfMAHZgUTEm11ohN9Fy54wao2HFk1VM4eplijX6pFGycA4yhKy73A/aesKhghVPzR+FaSmg==", "dependencies": { - "@react-navigation/elements": "^1.3.6", + "@react-navigation/elements": "^1.3.9", "color": "^4.2.3", "warn-once": "^0.1.0" }, @@ -4535,11 +4598,11 @@ } }, "node_modules/@react-navigation/core": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.0.tgz", - "integrity": "sha512-tpc0Ak/DiHfU3LlYaRmIY7vI4sM/Ru0xCet6runLUh9aABf4wiLgxyFJ5BtoWq6xFF8ymYEA/KWtDhetQ24YiA==", + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.3.tgz", + "integrity": "sha512-+HGHeEq7GK029Jy2jFkV2uQYc6a6AurjjUAVFlSz5tsNo4L5E3ZCzo7sk5+lcvt0Agdedf5Q+wTiWjT7IrixgA==", "dependencies": { - "@react-navigation/routers": "^6.1.3", + "@react-navigation/routers": "^6.1.5", "escape-string-regexp": "^4.0.0", "nanoid": "^3.1.23", "query-string": "^7.0.0", @@ -4551,11 +4614,11 @@ } }, "node_modules/@react-navigation/drawer": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@react-navigation/drawer/-/drawer-6.5.0.tgz", - "integrity": "sha512-ma3qPjAfbwF07xd1w1gaWdcvYWmT4F+Z098q2J7XGbHw8yTGQYiNTnD1NMKerXwxM24vui2tMuFHA54F1rIvHQ==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/@react-navigation/drawer/-/drawer-6.5.3.tgz", + "integrity": "sha512-5HP3aTH/yL/F8WS7S8Pa3CUGeRZ7sqAMjWatV6Z0nMBpQ0xRiobpds3jXkiedlPejUVZYcbU6YoJ1XQXHRaOkg==", "dependencies": { - "@react-navigation/elements": "^1.3.6", + "@react-navigation/elements": "^1.3.9", "color": "^4.2.3", "warn-once": "^0.1.0" }, @@ -4570,9 +4633,9 @@ } }, "node_modules/@react-navigation/elements": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.6.tgz", - "integrity": "sha512-pNJ8R9JMga6SXOw6wGVN0tjmE6vegwPmJBL45SEMX2fqTfAk2ykDnlJHodRpHpAgsv0DaI8qX76z3A+aqKSU0w==", + "version": "1.3.9", + "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.9.tgz", + "integrity": "sha512-V9aIZN19ufaKWlXT4UcM545tDiEt9DIQS+74pDgbnzoQcDypn0CvSqWopFhPACMdJatgmlZUuOrrMfTeNrBWgA==", "peerDependencies": { "@react-navigation/native": "^6.0.0", "react": "*", @@ -4581,11 +4644,11 @@ } }, "node_modules/@react-navigation/native": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-6.0.13.tgz", - "integrity": "sha512-CwaJcAGbhv3p3ECablxBkw8QBCGDWXqVRwQ4QbelajNW623m3sNTC9dOF6kjp8au6Rg9B5e0KmeuY0xWbPk79A==", + "version": "6.0.16", + "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-6.0.16.tgz", + "integrity": "sha512-YVmzypkDppV/vAG+66KTJ2RFtPjhDTLLjgk8TNTCHG3pahq1q13zbnEPjqB42bU4kgL5SG17O4saErt1DJaWQg==", "dependencies": { - "@react-navigation/core": "^6.4.0", + "@react-navigation/core": "^6.4.3", "escape-string-regexp": "^4.0.0", "fast-deep-equal": "^3.1.3", "nanoid": "^3.1.23" @@ -4596,11 +4659,11 @@ } }, "node_modules/@react-navigation/native-stack": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@react-navigation/native-stack/-/native-stack-6.9.1.tgz", - "integrity": "sha512-aOuJP97ge6NRz8wH6sDKfLTfdygGmraYh0apKrrVbGvMnflbPX4kpjQiAQcUPUpMeas0betH/Su8QubNL8HEkg==", + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/@react-navigation/native-stack/-/native-stack-6.9.4.tgz", + "integrity": "sha512-R40G2Zfo748hE4+we/TUAEClw53l0QdFDJ0q/9VS1moxgI4zUopdBxN5SmF32OMFfkedMRAT9J+aVbwgmdn7pA==", "dependencies": { - "@react-navigation/elements": "^1.3.6", + "@react-navigation/elements": "^1.3.9", "warn-once": "^0.1.0" }, "peerDependencies": { @@ -4612,9 +4675,9 @@ } }, "node_modules/@react-navigation/routers": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-6.1.3.tgz", - "integrity": "sha512-idJotMEzHc3haWsCh7EvnnZMKxvaS4YF/x2UyFBkNFiEFUaEo/1ioQU6qqmVLspdEv4bI/dLm97hQo7qD8Yl7Q==", + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-6.1.5.tgz", + "integrity": "sha512-JzMRiRRu8J0yUMC7BV8wOVzevjkHnIPONbpCTL/vH5yceTm+dSH/U3esIObgk8wYYbov+jYlVhwUQNGRb2to6g==", "dependencies": { "nanoid": "^3.1.23" } @@ -4730,9 +4793,9 @@ } }, "node_modules/@types/node": { - "version": "18.11.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", - "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==" + "version": "18.11.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.10.tgz", + "integrity": "sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ==" }, "node_modules/@types/prop-types": { "version": "15.7.5", @@ -4934,9 +4997,9 @@ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" }, "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -4951,9 +5014,9 @@ "integrity": "sha512-Quji6+8kLBC3NnBeo14nPDq0+2jUs5s3/xEye+udFHumHhRk4M7aAMXp/PBJqkKYGuuyR9M/6Dq7d2AViiGmhw==" }, "node_modules/application-config-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/application-config-path/-/application-config-path-0.1.0.tgz", - "integrity": "sha512-lljTpVvFteShrHuKRvweZfa9o/Nc34Y8r5/1Lqh/yyKaspRT2J3fkEiSSk1YLG8ZSVyU7yHysRy9zcDDS2aH1Q==" + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/application-config-path/-/application-config-path-0.1.1.tgz", + "integrity": "sha512-zy9cHePtMP0YhwG+CfHm0bgwdnga2X3gZexpdCwEj//dpb+TKajtiC8REEUJUSq6Ab4f9cgNy2l8ObXzCXFkEw==" }, "node_modules/arg": { "version": "4.1.0", @@ -5043,11 +5106,6 @@ "node": ">=4" } }, - "node_modules/ast-types/node_modules/tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" - }, "node_modules/astral-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", @@ -5180,16 +5238,17 @@ "integrity": "sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ==" }, "node_modules/babel-preset-expo": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-9.2.0.tgz", - "integrity": "sha512-aM2htiNx0H49H+MWCp9+cKVSdcdNSn0tbE5Dln/GO1xna4ZlnA30clbfClcYJFUcZtW90IsYeZwQ/hj8zyWhNA==", + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-9.2.2.tgz", + "integrity": "sha512-69cSPObZWFz0AaUT6IhCu2VzPVTICUtXzhX5ecoDttFe+9wb9yMV8m7rBNZptJQ3wtiKB5iEL7/wvtKygPz/mQ==", "dependencies": { "@babel/plugin-proposal-decorators": "^7.12.9", + "@babel/plugin-proposal-object-rest-spread": "^7.12.13", "@babel/plugin-transform-react-jsx": "^7.12.17", "@babel/preset-env": "^7.12.9", "babel-plugin-module-resolver": "^4.1.0", "babel-plugin-react-native-web": "~0.18.2", - "metro-react-native-babel-preset": "~0.70.3" + "metro-react-native-babel-preset": "0.72.3" } }, "node_modules/babel-preset-fbjs": { @@ -5655,9 +5714,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001430", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001430.tgz", - "integrity": "sha512-IB1BXTZKPDVPM7cnV4iaKaHxckvdr/3xtctB3f7Hmenx3qYBhGtTZ//7EllK66aKXW98Lx0+7Yr0kxBtIt3tzg==", + "version": "1.0.30001435", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001435.tgz", + "integrity": "sha512-kdCkUTjR+v4YAJelyiDTqiu82BDr4W4CP5sgTA0ZBmqn30XfS2ZghPLMowik9TPhS+psWJiUNxsqLyurDbmutA==", "funding": [ { "type": "opencollective", @@ -5733,9 +5792,12 @@ } }, "node_modules/ci-info": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.5.0.tgz", - "integrity": "sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==" + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.0.tgz", + "integrity": "sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==", + "engines": { + "node": ">=8" + } }, "node_modules/class-utils": { "version": "0.3.6", @@ -6167,9 +6229,9 @@ } }, "node_modules/core-js-compat": { - "version": "3.26.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.0.tgz", - "integrity": "sha512-piOX9Go+Z4f9ZiBFLnZ5VrOpBl0h7IGCkiFUN11QTe6LjAvOT3ifL/5TdoizMh99hcGy5SoLyWbapIY/PIb/3A==", + "version": "3.26.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.1.tgz", + "integrity": "sha512-622/KzTudvXCDLRw70iHW4KKs1aGpcRcowGWyYJr2DEBfRrd6hNJybxSWJFuZYD4ma86xhrwDDHxmDaIq4EA8A==", "dependencies": { "browserslist": "^4.21.4" }, @@ -6262,12 +6324,11 @@ } }, "node_modules/css-in-js-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz", - "integrity": "sha512-PJF0SpJT+WdbVVt0AOYp9C8GnuruRlL/UFW7932nLWmFLQTaWEzTBQEx7/hn4BuV+WON75iAViSUJLiU3PKbpA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz", + "integrity": "sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==", "dependencies": { - "hyphenate-style-name": "^1.0.2", - "isobject": "^3.0.1" + "hyphenate-style-name": "^1.0.3" } }, "node_modules/css-mediaquery": { @@ -6937,9 +6998,9 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/expo": { - "version": "46.0.16", - "resolved": "https://registry.npmjs.org/expo/-/expo-46.0.16.tgz", - "integrity": "sha512-lZETkf3t+gbZjKjSceIpU7I8Rmm5nZ0ZG1WPzNBBbm+k64/+kKV96s6RqS37W1TTDpIbd+AucT9kKpvtv0JB2A==", + "version": "46.0.17", + "resolved": "https://registry.npmjs.org/expo/-/expo-46.0.17.tgz", + "integrity": "sha512-rB+KMvjU3lFMkec5LcVFFn0Q2iJUEIoyB9TckKMirA15H5mW4yZMao0ilR7239fJ5ytVoDC8SIf7ZAvTmiMuMw==", "dependencies": { "@babel/runtime": "^7.14.0", "@expo/cli": "0.3.2", @@ -6953,7 +7014,7 @@ "expo-font": "~10.2.1", "expo-keep-awake": "~10.2.0", "expo-modules-autolinking": "0.10.3", - "expo-modules-core": "0.11.8", + "expo-modules-core": "0.11.9", "fbemitter": "^3.0.0", "getenv": "^1.0.0", "invariant": "^2.2.4", @@ -6978,19 +7039,42 @@ } }, "node_modules/expo-asset": { - "version": "8.6.1", - "resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-8.6.1.tgz", - "integrity": "sha512-urbUp1YtwH2J0Qc3inGQJdqTjWKML77SeMNgff+iR9MUE8gDkFqSCDjrBi7i5Oj5DDtq43mmtDg8G8ei6Vchcg==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-8.6.2.tgz", + "integrity": "sha512-XqlXjkuUCEiojbHwbHPjQs1oboRz6w3eV96+9NBD+wb3EUqgAAYY2Do+IWyVCAl8UIFbFi3xzMiqk0Xm9+H8uQ==", "dependencies": { "blueimp-md5": "^2.10.0", - "expo-constants": "~13.2.2", - "expo-file-system": "~14.1.0", + "expo-constants": "~14.0.0", + "expo-file-system": "~15.1.0", "invariant": "^2.2.4", "md5-file": "^3.2.3", "path-browserify": "^1.0.0", "url-parse": "^1.5.9" } }, + "node_modules/expo-asset/node_modules/expo-constants": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-14.0.2.tgz", + "integrity": "sha512-wzV3nrzTXTI8yG0tfas3fnqCfKV6YE+1GphEREyVDAShEB6mBInX1b6HgtpHFy2wOtnml+lPVmTCeGtjjLnZhA==", + "dependencies": { + "@expo/config": "~7.0.2", + "uuid": "^3.3.2" + }, + "peerDependencies": { + "expo": "*" + } + }, + "node_modules/expo-asset/node_modules/expo-file-system": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-15.1.1.tgz", + "integrity": "sha512-MYYDKxjLo9VOkvGHqym5EOAUS+ero9O66X5zI+EXJzqNznKvnfScdXeeAaQzShmWtmLkdVDCoYFGOaTvTA1wTQ==", + "dependencies": { + "uuid": "^3.4.0" + }, + "peerDependencies": { + "expo": "*" + } + }, "node_modules/expo-constants": { "version": "13.2.4", "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-13.2.4.tgz", @@ -7076,9 +7160,9 @@ } }, "node_modules/expo-keep-awake": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-10.2.0.tgz", - "integrity": "sha512-kIRtO4Hmrvxh4E45IPWG/NiUZsuRe1AQwBT09pq+kx8nm6tUS4B9TeL6+1NFy+qVBLbGKDqoQD5Ez7XYTFtBeQ==", + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-10.2.1.tgz", + "integrity": "sha512-UBge1BwzDPhUFX0gKu9eDLwEFj4LGiqrOogNoEYxcosM1SwhkbWwPrd3zZtl53LLz02TxEi/CI/MUGJJsrVQLw==", "peerDependencies": { "expo": "*" } @@ -7196,9 +7280,9 @@ } }, "node_modules/expo-modules-core": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-0.11.8.tgz", - "integrity": "sha512-goC2ghZFVaV6nXEbk+kz9oKnQmqW8fHVUCSPxC0QXhV0ay1dA9Ki6qqMPagkBJUPAz89NsNqW3bYR6DFXq7lvA==", + "version": "0.11.9", + "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-0.11.9.tgz", + "integrity": "sha512-6AlOE4KHN3/WWbY8hH7W6ceuIFj0qbk1N+UhmMhiCEUas3NvXA6wcH3xjO+8JZ+BRcIB9M4QEeX72j6vDDuExg==", "dependencies": { "compare-versions": "^3.4.0", "invariant": "^2.2.4" @@ -7270,9 +7354,9 @@ } }, "node_modules/expo-status-bar": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-1.4.0.tgz", - "integrity": "sha512-vh98g8qMIjig/2XTBsoAWS6Vo2dIIwDWjB3/GiuZ9Lazpxc9GO/APfJ4dar7MibzIDUKIrjotrcL6rLdPH13Ew==" + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-1.4.2.tgz", + "integrity": "sha512-ZWjO6D4ARGYfAd3SWDD3STNudHDhyBZDZjhhseqoEmsf7bS9ykny8KKOhlzJW24qIQNPhkgdvHhaw9fQwMJy3Q==" }, "node_modules/expo-web-browser": { "version": "11.0.0", @@ -7370,6 +7454,11 @@ "node": ">=8.6.0" } }, + "node_modules/fast-loops": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/fast-loops/-/fast-loops-1.1.3.tgz", + "integrity": "sha512-8EZzEP0eKkEEVX+drtd9mtuQ+/QrlfW/5MlwcwK5Nds6EkZ/tRzEexkzUY2mIssnAyVLT+TKHuRXmFNNXYUd6g==" + }, "node_modules/fastq": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", @@ -7825,11 +7914,6 @@ "graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, - "node_modules/graphql-tag/node_modules/tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" - }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -8047,9 +8131,9 @@ ] }, "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.1.tgz", + "integrity": "sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==", "engines": { "node": ">= 4" } @@ -8126,11 +8210,12 @@ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "node_modules/inline-style-prefixer": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-6.0.1.tgz", - "integrity": "sha512-AsqazZ8KcRzJ9YPN1wMH2aNM7lkWQ8tSPrW5uDk1ziYwiAPWSZnUsC7lfZq+BDqLqz0B4Pho5wscWcJzVvRzDQ==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-6.0.4.tgz", + "integrity": "sha512-FwXmZC2zbeeS7NzGjJ6pAiqRhXR0ugUShSNb6GApMl6da0/XGc4MOJsoWAywia52EEWbXNSy0pzkwz/+Y+swSg==", "dependencies": { - "css-in-js-utils": "^2.0.0" + "css-in-js-utils": "^3.1.0", + "fast-loops": "^1.1.3" } }, "node_modules/internal-ip": { @@ -9661,9 +9746,9 @@ } }, "node_modules/metro-react-native-babel-preset": { - "version": "0.70.3", - "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.70.3.tgz", - "integrity": "sha512-4Nxc1zEiHEu+GTdEMEsHnRgfaBkg8f/Td3+FcQ8NTSvs+xL3LBrQy6N07idWSQZHIdGFf+tTHvRfSIWLD8u8Tg==", + "version": "0.72.3", + "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.72.3.tgz", + "integrity": "sha512-uJx9y/1NIqoYTp6ZW1osJ7U5ZrXGAJbOQ/Qzl05BdGYvN1S7Qmbzid6xOirgK0EIT0pJKEEh1s8qbassYZe4cw==", "dependencies": { "@babel/core": "^7.14.0", "@babel/plugin-proposal-async-generator-functions": "^7.0.0", @@ -9726,6 +9811,55 @@ "@babel/core": "*" } }, + "node_modules/metro-react-native-babel-transformer/node_modules/metro-react-native-babel-preset": { + "version": "0.70.3", + "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.70.3.tgz", + "integrity": "sha512-4Nxc1zEiHEu+GTdEMEsHnRgfaBkg8f/Td3+FcQ8NTSvs+xL3LBrQy6N07idWSQZHIdGFf+tTHvRfSIWLD8u8Tg==", + "dependencies": { + "@babel/core": "^7.14.0", + "@babel/plugin-proposal-async-generator-functions": "^7.0.0", + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-export-default-from": "^7.0.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/plugin-proposal-optional-catch-binding": "^7.0.0", + "@babel/plugin-proposal-optional-chaining": "^7.0.0", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/plugin-syntax-export-default-from": "^7.0.0", + "@babel/plugin-syntax-flow": "^7.2.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-syntax-optional-chaining": "^7.0.0", + "@babel/plugin-transform-arrow-functions": "^7.0.0", + "@babel/plugin-transform-async-to-generator": "^7.0.0", + "@babel/plugin-transform-block-scoping": "^7.0.0", + "@babel/plugin-transform-classes": "^7.0.0", + "@babel/plugin-transform-computed-properties": "^7.0.0", + "@babel/plugin-transform-destructuring": "^7.0.0", + "@babel/plugin-transform-exponentiation-operator": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0", + "@babel/plugin-transform-function-name": "^7.0.0", + "@babel/plugin-transform-literals": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.0.0", + "@babel/plugin-transform-parameters": "^7.0.0", + "@babel/plugin-transform-react-display-name": "^7.0.0", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/plugin-transform-react-jsx-self": "^7.0.0", + "@babel/plugin-transform-react-jsx-source": "^7.0.0", + "@babel/plugin-transform-runtime": "^7.0.0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0", + "@babel/plugin-transform-spread": "^7.0.0", + "@babel/plugin-transform-sticky-regex": "^7.0.0", + "@babel/plugin-transform-template-literals": "^7.0.0", + "@babel/plugin-transform-typescript": "^7.5.0", + "@babel/plugin-transform-unicode-regex": "^7.0.0", + "@babel/template": "^7.0.0", + "react-refresh": "^0.4.0" + }, + "peerDependencies": { + "@babel/core": "*" + } + }, "node_modules/metro-resolver": { "version": "0.70.3", "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.70.3.tgz", @@ -9908,6 +10042,55 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/metro/node_modules/metro-react-native-babel-preset": { + "version": "0.70.3", + "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.70.3.tgz", + "integrity": "sha512-4Nxc1zEiHEu+GTdEMEsHnRgfaBkg8f/Td3+FcQ8NTSvs+xL3LBrQy6N07idWSQZHIdGFf+tTHvRfSIWLD8u8Tg==", + "dependencies": { + "@babel/core": "^7.14.0", + "@babel/plugin-proposal-async-generator-functions": "^7.0.0", + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-export-default-from": "^7.0.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/plugin-proposal-optional-catch-binding": "^7.0.0", + "@babel/plugin-proposal-optional-chaining": "^7.0.0", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/plugin-syntax-export-default-from": "^7.0.0", + "@babel/plugin-syntax-flow": "^7.2.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-syntax-optional-chaining": "^7.0.0", + "@babel/plugin-transform-arrow-functions": "^7.0.0", + "@babel/plugin-transform-async-to-generator": "^7.0.0", + "@babel/plugin-transform-block-scoping": "^7.0.0", + "@babel/plugin-transform-classes": "^7.0.0", + "@babel/plugin-transform-computed-properties": "^7.0.0", + "@babel/plugin-transform-destructuring": "^7.0.0", + "@babel/plugin-transform-exponentiation-operator": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0", + "@babel/plugin-transform-function-name": "^7.0.0", + "@babel/plugin-transform-literals": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.0.0", + "@babel/plugin-transform-parameters": "^7.0.0", + "@babel/plugin-transform-react-display-name": "^7.0.0", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/plugin-transform-react-jsx-self": "^7.0.0", + "@babel/plugin-transform-react-jsx-source": "^7.0.0", + "@babel/plugin-transform-runtime": "^7.0.0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0", + "@babel/plugin-transform-spread": "^7.0.0", + "@babel/plugin-transform-sticky-regex": "^7.0.0", + "@babel/plugin-transform-template-literals": "^7.0.0", + "@babel/plugin-transform-typescript": "^7.5.0", + "@babel/plugin-transform-unicode-regex": "^7.0.0", + "@babel/template": "^7.0.0", + "react-refresh": "^0.4.0" + }, + "peerDependencies": { + "@babel/core": "*" + } + }, "node_modules/metro/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -11053,9 +11236,9 @@ } }, "node_modules/postcss": { - "version": "8.4.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz", - "integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==", + "version": "8.4.19", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.19.tgz", + "integrity": "sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==", "funding": [ { "type": "opencollective", @@ -11207,9 +11390,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.0.10", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", - "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", + "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -11648,6 +11831,15 @@ "react-native": ">=0.48.4" } }, + "node_modules/react-native-pager-view": { + "version": "5.4.24", + "resolved": "https://registry.npmjs.org/react-native-pager-view/-/react-native-pager-view-5.4.24.tgz", + "integrity": "sha512-dRMB7i3B+mu4NCeIN6gqbR/kC/rr2wzqO0gisXDdJwJr78G24sWoTNpLEDFo3G8TFHY9nTMutVl5CUvkN2dp6g==", + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, "node_modules/react-native-paper": { "version": "4.12.5", "resolved": "https://registry.npmjs.org/react-native-paper/-/react-native-paper-4.12.5.tgz", @@ -11774,6 +11966,16 @@ "prop-types": "^15.5.8" } }, + "node_modules/react-native-star-rating-widget": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/react-native-star-rating-widget/-/react-native-star-rating-widget-1.5.0.tgz", + "integrity": "sha512-dZUD38h47RvQtMXjjiNMZSjww2r28QRQ5QAQl7wo8+mxwILoDu3Fznom+rSVDjOQ5S2En5wuNqSQ801tr9Dx+w==", + "peerDependencies": { + "react": "*", + "react-native": "*", + "react-native-svg": "*" + } + }, "node_modules/react-native-svg": { "version": "12.3.0", "resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-12.3.0.tgz", @@ -11787,6 +11989,19 @@ "react-native": ">=0.50.0" } }, + "node_modules/react-native-tab-view": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/react-native-tab-view/-/react-native-tab-view-3.3.2.tgz", + "integrity": "sha512-s0xr+wiMBHdjsWgbPTyZemgv7jJ+zKPBw/MIQIlKAMo4VCNV1vAZEbOHaHpGbqgYFwsmFXjKZNXQ5UJAIJXlDQ==", + "dependencies": { + "use-latest-callback": "^0.1.5" + }, + "peerDependencies": { + "react": "*", + "react-native": "*", + "react-native-pager-view": "*" + } + }, "node_modules/react-native-vector-icons": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-9.2.0.tgz", @@ -11916,6 +12131,7 @@ "version": "4.4.4", "resolved": "https://registry.npmjs.org/react-navigation/-/react-navigation-4.4.4.tgz", "integrity": "sha512-08Nzy1aKEd73496CsuzN49vLFmxPKYF5WpKGgGvkQ10clB79IRM2BtAfVl6NgPKuUM8FXq1wCsrjo/c5ftl5og==", + "deprecated": "This package is no longer supported. Please use @react-navigation/native instead. See https://reactnavigation.org/docs/getting-started/ for usage guide", "dependencies": { "@react-navigation/core": "^3.7.9", "@react-navigation/native": "^3.8.4" @@ -12053,11 +12269,6 @@ "node": ">=0.10.0" } }, - "node_modules/recast/node_modules/tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" - }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -12075,14 +12286,14 @@ } }, "node_modules/regenerator-runtime": { - "version": "0.13.10", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz", - "integrity": "sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==" + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, "node_modules/regenerator-transform": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.0.tgz", - "integrity": "sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==", + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", + "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", "dependencies": { "@babel/runtime": "^7.8.4" } @@ -12100,16 +12311,16 @@ } }, "node_modules/regexpu-core": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.1.tgz", - "integrity": "sha512-HrnlNtpvqP1Xkb28tMhBUO2EbyUHdQlsnlAhzWcwHy8WJR53UWr7/MAvqrsQKMbV4qdpv03oTMG8iIhfsPFktQ==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz", + "integrity": "sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==", "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.1.0", "regjsgen": "^0.7.1", "regjsparser": "^0.9.1", "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.0.0" + "unicode-match-property-value-ecmascript": "^2.1.0" }, "engines": { "node": ">=4" @@ -13167,9 +13378,9 @@ "integrity": "sha512-EBNuMVSxpssuFcJq/c4zmZ4tpCyX9E27hz5xPJhw4URjRHcYXPHh8rDHY/tJsw5gtP0+tIL3IBYeQVIYjdZFhg==" }, "node_modules/sucrase": { - "version": "3.28.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.28.0.tgz", - "integrity": "sha512-TK9600YInjuiIhVM3729rH4ZKPOsGeyXUwY+Ugu9eilNbdTFyHr6XcAGYbRVZPDgWj6tgI7bx95aaJjHnbffag==", + "version": "3.29.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.29.0.tgz", + "integrity": "sha512-bZPAuGA5SdFHuzqIhTAqt9fvNEo9rESqXIG3oiKdF8K4UmkQxC4KlNL3lVyAErXp+mPvUqZ5l13qx6TrDIGf3A==", "dependencies": { "commander": "^4.0.0", "glob": "7.1.6", @@ -13253,9 +13464,9 @@ } }, "node_modules/tailwindcss": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.2.tgz", - "integrity": "sha512-c2GtSdqg+harR4QeoTmex0Ngfg8IIHNeLQH5yr2B9uZbZR1Xt1rYbjWOWTcj3YLTZhrmZnPowoQDbSRFyZHQ5Q==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.4.tgz", + "integrity": "sha512-AhwtHCKMtR71JgeYDaswmZXhPcW9iuI9Sp2LvZPo9upDZ7231ZJ7eA9RaURbhpXGVlrjX4cFNlB4ieTetEb7hQ==", "dependencies": { "arg": "^5.0.2", "chokidar": "^3.5.3", @@ -13607,9 +13818,9 @@ "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" }, "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" }, "node_modules/type-fest": { "version": "0.12.0", @@ -13715,9 +13926,9 @@ } }, "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", - "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", "engines": { "node": ">=4" } @@ -14338,25 +14549,25 @@ } }, "@babel/compat-data": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.1.tgz", - "integrity": "sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ==" + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz", + "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==" }, "@babel/core": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.2.tgz", - "integrity": "sha512-w7DbG8DtMrJcFOi4VrLm+8QM4az8Mo+PuLBKLp2zrYRCow8W/f9xiXm5sN53C8HksCyDQwCKha9JiDoIyPjT2g==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.5.tgz", + "integrity": "sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==", "requires": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.2", + "@babel/generator": "^7.20.5", "@babel/helper-compilation-targets": "^7.20.0", "@babel/helper-module-transforms": "^7.20.2", - "@babel/helpers": "^7.20.1", - "@babel/parser": "^7.20.2", + "@babel/helpers": "^7.20.5", + "@babel/parser": "^7.20.5", "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.2", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -14365,11 +14576,11 @@ } }, "@babel/generator": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.2.tgz", - "integrity": "sha512-SD75PMIK6i9H8G/tfGvB4KKl4Nw6Ssos9nGgYwxbgyTP0iX/Z55DveoH86rmUB/YHTQQ+ZC0F7xxaY8l2OF44Q==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.5.tgz", + "integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==", "requires": { - "@babel/types": "^7.20.2", + "@babel/types": "^7.20.5", "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, @@ -14415,9 +14626,9 @@ } }, "@babel/helper-create-class-features-plugin": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.2.tgz", - "integrity": "sha512-k22GoYRAHPYr9I+Gvy2ZQlAe5mGy8BqWst2wRt8cwIufWTxrsVshhIBvYNqC80N0GSFWTsqRVexOtfzlgOEDvA==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.5.tgz", + "integrity": "sha512-3RCdA/EmEaikrhayahwToF0fpweU/8o2p8vhc1c/1kftHOdTKuC65kik/TLc+qfbS8JKw4qqJbne4ovICDhmww==", "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-environment-visitor": "^7.18.9", @@ -14429,12 +14640,12 @@ } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz", - "integrity": "sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.20.5.tgz", + "integrity": "sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==", "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.1.0" + "regexpu-core": "^5.2.1" } }, "@babel/helper-define-polyfill-provider": { @@ -14587,24 +14798,24 @@ "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==" }, "@babel/helper-wrap-function": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz", - "integrity": "sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz", + "integrity": "sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==", "requires": { "@babel/helper-function-name": "^7.19.0", "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5" } }, "@babel/helpers": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.1.tgz", - "integrity": "sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg==", + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz", + "integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==", "requires": { "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.0" + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5" } }, "@babel/highlight": { @@ -14618,9 +14829,9 @@ } }, "@babel/parser": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.2.tgz", - "integrity": "sha512-afk318kh2uKbo7BEj2QtEi8HVCGrwHUffrYDy7dgVcSa2j9lY3LDjPzcyGdpX7xgm35aWqvciZJ4WKmdF/SxYg==" + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz", + "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==" }, "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { "version": "7.18.6", @@ -14671,11 +14882,11 @@ } }, "@babel/plugin-proposal-decorators": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.20.2.tgz", - "integrity": "sha512-nkBH96IBmgKnbHQ5gXFrcmez+Z9S2EIDKDQGp005ROqBigc88Tky4rzCnlP/lnlj245dCEQl4/YyV0V1kYh5dw==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.20.5.tgz", + "integrity": "sha512-Lac7PpRJXcC3s9cKsBfl+uc+DYXU5FD06BrTFunQO6QIQT+DwyzDPURAowI3bcvD1dZF/ank1Z5rstUJn3Hn4Q==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.20.2", + "@babel/helper-create-class-features-plugin": "^7.20.5", "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-replace-supers": "^7.19.1", "@babel/helper-split-export-declaration": "^7.18.6", @@ -14786,13 +14997,13 @@ } }, "@babel/plugin-proposal-private-property-in-object": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz", - "integrity": "sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.20.5.tgz", + "integrity": "sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ==", "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.20.5", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" } }, @@ -14992,9 +15203,9 @@ } }, "@babel/plugin-transform-block-scoping": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.2.tgz", - "integrity": "sha512-y5V15+04ry69OV2wULmwhEA6jwSWXO1TwAtIwiPXcvHcoOQUqpyMVd2bDsQJMW8AurjulIyUV8kDqtjSwHy1uQ==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.5.tgz", + "integrity": "sha512-WvpEIW9Cbj9ApF3yJCjIEEf1EiNJLtXagOrL5LNWEZOo3jv8pmPoYTSNJQvqej8OavVlgOoOPw6/htGZro6IkA==", "requires": { "@babel/helper-plugin-utils": "^7.20.2" } @@ -15140,12 +15351,12 @@ } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz", - "integrity": "sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz", + "integrity": "sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==", "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.19.0", - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-create-regexp-features-plugin": "^7.20.5", + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-new-target": { @@ -15174,11 +15385,11 @@ } }, "@babel/plugin-transform-parameters": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.1.tgz", - "integrity": "sha512-nDvKLrAvl+kf6BOy1UJ3MGwzzfTMgppxwiD2Jb4LO3xjYyZq30oQzDNJbCQpMdG9+j2IXHoiMrw5Cm/L6ZoxXQ==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.5.tgz", + "integrity": "sha512-h7plkOmcndIUWXZFLgpbrh2+fXAi47zcUX7IrOQuZdLD0I0KvjJ6cvo3BEcAOsDOcZhVKGJqv07mkSqK0y2isQ==", "requires": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-property-literals": { @@ -15226,12 +15437,12 @@ } }, "@babel/plugin-transform-regenerator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz", - "integrity": "sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz", + "integrity": "sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "regenerator-transform": "^0.15.0" + "@babel/helper-plugin-utils": "^7.20.2", + "regenerator-transform": "^0.15.1" } }, "@babel/plugin-transform-reserved-words": { @@ -15450,11 +15661,11 @@ } }, "@babel/runtime": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.1.tgz", - "integrity": "sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==", + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.6.tgz", + "integrity": "sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==", "requires": { - "regenerator-runtime": "^0.13.10" + "regenerator-runtime": "^0.13.11" } }, "@babel/template": { @@ -15468,26 +15679,26 @@ } }, "@babel/traverse": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.1.tgz", - "integrity": "sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.5.tgz", + "integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==", "requires": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.1", + "@babel/generator": "^7.20.5", "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-function-name": "^7.19.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.1", - "@babel/types": "^7.20.0", + "@babel/parser": "^7.20.5", + "@babel/types": "^7.20.5", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.2.tgz", - "integrity": "sha512-FnnvsNWgZCr232sqtXggapvlkk/tuwR/qhGzcmxI0GXLCjmPYQPzio2FbdlWuY6y1sHFfQKk+rRbUZ9VStQMog==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz", + "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==", "requires": { "@babel/helper-string-parser": "^7.19.4", "@babel/helper-validator-identifier": "^7.19.1", @@ -15667,13 +15878,13 @@ } }, "@expo/config": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@expo/config/-/config-7.0.1.tgz", - "integrity": "sha512-4lu0wr45XXJ2MXiLAm2+fmOyy/jjqF3NuDm92fO6nuulRzEEvTP4w3vsibJ690rT81ohtvhpruKhkRs0wSjKWA==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@expo/config/-/config-7.0.3.tgz", + "integrity": "sha512-joVtB5o+NF40Tmsdp65UzryRtbnCuMbXkVO4wJnNJO4aaK0EYLdHCYSewORVqNcDfGN0LphQr8VTG2npbd9CJA==", "requires": { "@babel/code-frame": "~7.10.4", - "@expo/config-plugins": "~5.0.1", - "@expo/config-types": "^46.0.1", + "@expo/config-plugins": "~5.0.3", + "@expo/config-types": "^47.0.0", "@expo/json-file": "8.2.36", "getenv": "^1.0.0", "glob": "7.1.6", @@ -15700,11 +15911,11 @@ } }, "@expo/config-plugins": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-5.0.1.tgz", - "integrity": "sha512-1OfnsOrfeSkB0VZfT01UjQ5Uq6p+yYbq8yNkj0e99K/6NLHpyvIxj+5tZIV0nQXgkOcqBIABL2uA7lwB8CkaBQ==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-5.0.4.tgz", + "integrity": "sha512-vzUcVpqOMs3h+hyRdhGwk+eGIOhXa5xYdd92yO17RMNHav3v/+ekMbs7XA2c3lepMO8Yd4/5hqmRw9ZTL6jGzg==", "requires": { - "@expo/config-types": "^46.0.0", + "@expo/config-types": "^47.0.0", "@expo/json-file": "8.2.36", "@expo/plist": "0.0.18", "@expo/sdk-runtime-versions": "^1.0.0", @@ -15775,9 +15986,9 @@ } }, "@expo/config-types": { - "version": "46.0.2", - "resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-46.0.2.tgz", - "integrity": "sha512-PXkmOgNwRyBfgVT1HmFZhfh3Qm7WKKyV6mk3/5HJ/LzPh1t+Zs2JrWX8U2YncTLV1QzV7nV8tnkyvszzqnZEzQ==" + "version": "47.0.0", + "resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-47.0.0.tgz", + "integrity": "sha512-r0pWfuhkv7KIcXMUiNACJmJKKwlTBGMw9VZHNdppS8/0Nve8HZMTkNRFQzTHW1uH3pBj8jEXpyw/2vSWDHex9g==" }, "@expo/configure-splash-screen": { "version": "0.6.0", @@ -15827,17 +16038,20 @@ } }, "@expo/dev-server": { - "version": "0.1.120", - "resolved": "https://registry.npmjs.org/@expo/dev-server/-/dev-server-0.1.120.tgz", - "integrity": "sha512-x5/jCv0EOpz6FyehXpI5bgDQTVsGZYvgISkAw7n60RhtG+aid6N2CCR9SDMCH70XaUpFnfTW9qvderpCEj7Puw==", + "version": "0.1.123", + "resolved": "https://registry.npmjs.org/@expo/dev-server/-/dev-server-0.1.123.tgz", + "integrity": "sha512-N6UVzzeemfX0AONUSWInvkAAbqon8hRXpyYE/nMPaC6TvAmgGY5ILZAGoXwlpxwY2VKNT0Lx4s/UJ53ytIaHbA==", "requires": { "@expo/bunyan": "4.0.0", - "@expo/metro-config": "~0.4.0", + "@expo/metro-config": "~0.5.1", "@expo/osascript": "2.0.33", + "@expo/spawn-async": "^1.5.0", "body-parser": "1.19.0", "chalk": "^4.0.0", "connect": "^3.7.0", "fs-extra": "9.0.0", + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1", "node-fetch": "^2.6.0", "open": "^8.3.0", "resolve-from": "^5.0.0", @@ -15846,6 +16060,21 @@ "temp-dir": "^2.0.0" }, "dependencies": { + "@expo/metro-config": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-0.5.1.tgz", + "integrity": "sha512-Rvy4ZFgKNDfXO401z2OQF8fWbPj1lLVDL4GF1aqCIhCDHCKrezbwB0xejpcUyndJRCxBL2BMAM+P24t6cKv9Fw==", + "requires": { + "@expo/config": "~7.0.2", + "@expo/json-file": "8.2.36", + "chalk": "^4.1.0", + "debug": "^4.3.2", + "find-yarn-workspace-root": "~2.0.0", + "getenv": "^1.0.0", + "resolve-from": "^5.0.0", + "sucrase": "^3.20.0" + } + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -15929,9 +16158,9 @@ } }, "@expo/devcert": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@expo/devcert/-/devcert-1.0.0.tgz", - "integrity": "sha512-cahGyQCmpZmHpn2U04NR9KwsOIZy7Rhsw8Fg4q+A6563lIJxbkrgPnxq/O3NQAh3ohEvOXOOnoFx0b4yycCkpQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@expo/devcert/-/devcert-1.1.0.tgz", + "integrity": "sha512-ghUVhNJQOCTdQckSGTHctNp/0jzvVoMMkVh+6SHn+TZj8sU15U/npXIDt8NtQp0HedlPaCgkVdMu8Sacne0aEA==", "requires": { "application-config-path": "^0.1.0", "command-exists": "^1.2.4", @@ -15945,7 +16174,7 @@ "rimraf": "^2.6.2", "sudo-prompt": "^8.2.0", "tmp": "^0.0.33", - "tslib": "^1.10.0" + "tslib": "^2.4.0" }, "dependencies": { "debug": { @@ -15959,9 +16188,9 @@ } }, "@expo/image-utils": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.3.20.tgz", - "integrity": "sha512-NgF/80XENyCS+amwC0P6uk1fauEtUq7gijD19jvl2xknJaADq8M2dMCRHwWMVOXosr2v46f3Z++G/NjmyOVS7A==", + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.3.22.tgz", + "integrity": "sha512-uzq+RERAtkWypOFOLssFnXXqEqKjNj9eXN7e97d/EXUAojNcLDoXc0sL+F5B1I4qtlsnhX01kcpoIBBZD8wZNQ==", "requires": { "@expo/spawn-async": "1.5.0", "chalk": "^4.0.0", @@ -16134,6 +16363,37 @@ "sucrase": "^3.20.0" }, "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@expo/config": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@expo/config/-/config-7.0.1.tgz", + "integrity": "sha512-4lu0wr45XXJ2MXiLAm2+fmOyy/jjqF3NuDm92fO6nuulRzEEvTP4w3vsibJ690rT81ohtvhpruKhkRs0wSjKWA==", + "requires": { + "@babel/code-frame": "~7.10.4", + "@expo/config-plugins": "~5.0.1", + "@expo/config-types": "^46.0.1", + "@expo/json-file": "8.2.36", + "getenv": "^1.0.0", + "glob": "7.1.6", + "require-from-string": "^2.0.2", + "resolve-from": "^5.0.0", + "semver": "7.3.2", + "slugify": "^1.3.4", + "sucrase": "^3.20.0" + } + }, + "@expo/config-types": { + "version": "46.0.2", + "resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-46.0.2.tgz", + "integrity": "sha512-PXkmOgNwRyBfgVT1HmFZhfh3Qm7WKKyV6mk3/5HJ/LzPh1t+Zs2JrWX8U2YncTLV1QzV7nV8tnkyvszzqnZEzQ==" + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -16169,6 +16429,11 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -16189,9 +16454,9 @@ } }, "@expo/package-manager": { - "version": "0.0.56", - "resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-0.0.56.tgz", - "integrity": "sha512-PGk34uz4XDyhoNIlPh2D+BDsiXYuW2jXavTiax8d32uvHlRO6FN0cAsqlWD6fx3H2hRn8cU/leTuc4M7pYovCQ==", + "version": "0.0.57", + "resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-0.0.57.tgz", + "integrity": "sha512-Y4RpSL9EqaPF+Vd2GrK6r7Xx7Dv0Xdq3AGAD9C0KwV21WqP/scj/dpjxFY+ABwmdhNsFzYXb8fmDyh4tiKenPQ==", "requires": { "@expo/json-file": "8.2.36", "@expo/spawn-async": "^1.5.0", @@ -16274,14 +16539,14 @@ } }, "@expo/prebuild-config": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-5.0.3.tgz", - "integrity": "sha512-G4j1H3WFjRaiQ+FgFNULrnIm7RsQyjc4xp6lLTP2ydBv79wO3x8wAdeZvaZh7eOkfu9BESpQzACT1uuJTag5jg==", - "requires": { - "@expo/config": "7.0.1", - "@expo/config-plugins": "~5.0.1", - "@expo/config-types": "^46.0.0", - "@expo/image-utils": "0.3.20", + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-5.0.7.tgz", + "integrity": "sha512-D+TBpJUHe4+oTGFPb4o0rrw/h1xxc6wF+abJnbDHUkhnaeiHkE2O3ByS7FdiZ2FT36t0OKqeSKG/xFwWT3m1Ew==", + "requires": { + "@expo/config": "~7.0.2", + "@expo/config-plugins": "~5.0.3", + "@expo/config-types": "^47.0.0", + "@expo/image-utils": "0.3.22", "@expo/json-file": "8.2.36", "debug": "^4.3.1", "fs-extra": "^9.0.0", @@ -16708,9 +16973,9 @@ } }, "@react-native-async-storage/async-storage": { - "version": "1.17.10", - "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.17.10.tgz", - "integrity": "sha512-KrR021BmBLsA0TT1AAsfH16bHYy0MSbhdAeBAqpriak3GS1T2alFcdTUvn13p0ZW6FKRD6Bd3ryU2zhU/IYYJQ==", + "version": "1.17.11", + "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.17.11.tgz", + "integrity": "sha512-bzs45n5HNcDq6mxXnSsOHysZWn1SbbebNxldBXCQs8dSvF8Aor9KCdpm+TpnnGweK3R6diqsT8lFhX77VX0NFw==", "requires": { "merge-options": "^3.0.4" } @@ -17546,21 +17811,21 @@ "integrity": "sha512-K0aGNn1TjalKj+65D7ycc1//H9roAQ51GJVk5ZJQFb2teECGmzd86bYDC0aYdbRf7gtovescq4Zt6FR0tgXiHQ==" }, "@react-navigation/bottom-tabs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-6.4.0.tgz", - "integrity": "sha512-90CapiXjiWudbCiki9e6fOr/CECQRguIxv5OD7IBfbAMGX5GGiJpX8aqiHAz2DxpAz31v4JZcUr945+lFhXBfA==", + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-6.4.3.tgz", + "integrity": "sha512-nkuHJ31mEyrZZPswfMAHZgUTEm11ohN9Fy54wao2HFk1VM4eplijX6pFGycA4yhKy73A/aesKhghVPzR+FaSmg==", "requires": { - "@react-navigation/elements": "^1.3.6", + "@react-navigation/elements": "^1.3.9", "color": "^4.2.3", "warn-once": "^0.1.0" } }, "@react-navigation/core": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.0.tgz", - "integrity": "sha512-tpc0Ak/DiHfU3LlYaRmIY7vI4sM/Ru0xCet6runLUh9aABf4wiLgxyFJ5BtoWq6xFF8ymYEA/KWtDhetQ24YiA==", + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.3.tgz", + "integrity": "sha512-+HGHeEq7GK029Jy2jFkV2uQYc6a6AurjjUAVFlSz5tsNo4L5E3ZCzo7sk5+lcvt0Agdedf5Q+wTiWjT7IrixgA==", "requires": { - "@react-navigation/routers": "^6.1.3", + "@react-navigation/routers": "^6.1.5", "escape-string-regexp": "^4.0.0", "nanoid": "^3.1.23", "query-string": "^7.0.0", @@ -17569,45 +17834,45 @@ } }, "@react-navigation/drawer": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@react-navigation/drawer/-/drawer-6.5.0.tgz", - "integrity": "sha512-ma3qPjAfbwF07xd1w1gaWdcvYWmT4F+Z098q2J7XGbHw8yTGQYiNTnD1NMKerXwxM24vui2tMuFHA54F1rIvHQ==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/@react-navigation/drawer/-/drawer-6.5.3.tgz", + "integrity": "sha512-5HP3aTH/yL/F8WS7S8Pa3CUGeRZ7sqAMjWatV6Z0nMBpQ0xRiobpds3jXkiedlPejUVZYcbU6YoJ1XQXHRaOkg==", "requires": { - "@react-navigation/elements": "^1.3.6", + "@react-navigation/elements": "^1.3.9", "color": "^4.2.3", "warn-once": "^0.1.0" } }, "@react-navigation/elements": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.6.tgz", - "integrity": "sha512-pNJ8R9JMga6SXOw6wGVN0tjmE6vegwPmJBL45SEMX2fqTfAk2ykDnlJHodRpHpAgsv0DaI8qX76z3A+aqKSU0w==", + "version": "1.3.9", + "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.9.tgz", + "integrity": "sha512-V9aIZN19ufaKWlXT4UcM545tDiEt9DIQS+74pDgbnzoQcDypn0CvSqWopFhPACMdJatgmlZUuOrrMfTeNrBWgA==", "requires": {} }, "@react-navigation/native": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-6.0.13.tgz", - "integrity": "sha512-CwaJcAGbhv3p3ECablxBkw8QBCGDWXqVRwQ4QbelajNW623m3sNTC9dOF6kjp8au6Rg9B5e0KmeuY0xWbPk79A==", + "version": "6.0.16", + "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-6.0.16.tgz", + "integrity": "sha512-YVmzypkDppV/vAG+66KTJ2RFtPjhDTLLjgk8TNTCHG3pahq1q13zbnEPjqB42bU4kgL5SG17O4saErt1DJaWQg==", "requires": { - "@react-navigation/core": "^6.4.0", + "@react-navigation/core": "^6.4.3", "escape-string-regexp": "^4.0.0", "fast-deep-equal": "^3.1.3", "nanoid": "^3.1.23" } }, "@react-navigation/native-stack": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@react-navigation/native-stack/-/native-stack-6.9.1.tgz", - "integrity": "sha512-aOuJP97ge6NRz8wH6sDKfLTfdygGmraYh0apKrrVbGvMnflbPX4kpjQiAQcUPUpMeas0betH/Su8QubNL8HEkg==", + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/@react-navigation/native-stack/-/native-stack-6.9.4.tgz", + "integrity": "sha512-R40G2Zfo748hE4+we/TUAEClw53l0QdFDJ0q/9VS1moxgI4zUopdBxN5SmF32OMFfkedMRAT9J+aVbwgmdn7pA==", "requires": { - "@react-navigation/elements": "^1.3.6", + "@react-navigation/elements": "^1.3.9", "warn-once": "^0.1.0" } }, "@react-navigation/routers": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-6.1.3.tgz", - "integrity": "sha512-idJotMEzHc3haWsCh7EvnnZMKxvaS4YF/x2UyFBkNFiEFUaEo/1ioQU6qqmVLspdEv4bI/dLm97hQo7qD8Yl7Q==", + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-6.1.5.tgz", + "integrity": "sha512-JzMRiRRu8J0yUMC7BV8wOVzevjkHnIPONbpCTL/vH5yceTm+dSH/U3esIObgk8wYYbov+jYlVhwUQNGRb2to6g==", "requires": { "nanoid": "^3.1.23" } @@ -17711,9 +17976,9 @@ } }, "@types/node": { - "version": "18.11.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", - "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==" + "version": "18.11.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.10.tgz", + "integrity": "sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ==" }, "@types/prop-types": { "version": "15.7.5", @@ -17879,9 +18144,9 @@ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" }, "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -17893,9 +18158,9 @@ "integrity": "sha512-Quji6+8kLBC3NnBeo14nPDq0+2jUs5s3/xEye+udFHumHhRk4M7aAMXp/PBJqkKYGuuyR9M/6Dq7d2AViiGmhw==" }, "application-config-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/application-config-path/-/application-config-path-0.1.0.tgz", - "integrity": "sha512-lljTpVvFteShrHuKRvweZfa9o/Nc34Y8r5/1Lqh/yyKaspRT2J3fkEiSSk1YLG8ZSVyU7yHysRy9zcDDS2aH1Q==" + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/application-config-path/-/application-config-path-0.1.1.tgz", + "integrity": "sha512-zy9cHePtMP0YhwG+CfHm0bgwdnga2X3gZexpdCwEj//dpb+TKajtiC8REEUJUSq6Ab4f9cgNy2l8ObXzCXFkEw==" }, "arg": { "version": "4.1.0", @@ -17962,13 +18227,6 @@ "integrity": "sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA==", "requires": { "tslib": "^2.0.1" - }, - "dependencies": { - "tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" - } } }, "astral-regex": { @@ -18071,16 +18329,17 @@ "integrity": "sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ==" }, "babel-preset-expo": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-9.2.0.tgz", - "integrity": "sha512-aM2htiNx0H49H+MWCp9+cKVSdcdNSn0tbE5Dln/GO1xna4ZlnA30clbfClcYJFUcZtW90IsYeZwQ/hj8zyWhNA==", + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-9.2.2.tgz", + "integrity": "sha512-69cSPObZWFz0AaUT6IhCu2VzPVTICUtXzhX5ecoDttFe+9wb9yMV8m7rBNZptJQ3wtiKB5iEL7/wvtKygPz/mQ==", "requires": { "@babel/plugin-proposal-decorators": "^7.12.9", + "@babel/plugin-proposal-object-rest-spread": "^7.12.13", "@babel/plugin-transform-react-jsx": "^7.12.17", "@babel/preset-env": "^7.12.9", "babel-plugin-module-resolver": "^4.1.0", "babel-plugin-react-native-web": "~0.18.2", - "metro-react-native-babel-preset": "~0.70.3" + "metro-react-native-babel-preset": "0.72.3" } }, "babel-preset-fbjs": { @@ -18435,9 +18694,9 @@ "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==" }, "caniuse-lite": { - "version": "1.0.30001430", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001430.tgz", - "integrity": "sha512-IB1BXTZKPDVPM7cnV4iaKaHxckvdr/3xtctB3f7Hmenx3qYBhGtTZ//7EllK66aKXW98Lx0+7Yr0kxBtIt3tzg==" + "version": "1.0.30001435", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001435.tgz", + "integrity": "sha512-kdCkUTjR+v4YAJelyiDTqiu82BDr4W4CP5sgTA0ZBmqn30XfS2ZghPLMowik9TPhS+psWJiUNxsqLyurDbmutA==" }, "chalk": { "version": "2.4.2", @@ -18482,9 +18741,9 @@ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" }, "ci-info": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.5.0.tgz", - "integrity": "sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==" + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.0.tgz", + "integrity": "sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==" }, "class-utils": { "version": "0.3.6", @@ -18837,9 +19096,9 @@ "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==" }, "core-js-compat": { - "version": "3.26.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.0.tgz", - "integrity": "sha512-piOX9Go+Z4f9ZiBFLnZ5VrOpBl0h7IGCkiFUN11QTe6LjAvOT3ifL/5TdoizMh99hcGy5SoLyWbapIY/PIb/3A==", + "version": "3.26.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.1.tgz", + "integrity": "sha512-622/KzTudvXCDLRw70iHW4KKs1aGpcRcowGWyYJr2DEBfRrd6hNJybxSWJFuZYD4ma86xhrwDDHxmDaIq4EA8A==", "requires": { "browserslist": "^4.21.4" } @@ -18912,12 +19171,11 @@ "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==" }, "css-in-js-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz", - "integrity": "sha512-PJF0SpJT+WdbVVt0AOYp9C8GnuruRlL/UFW7932nLWmFLQTaWEzTBQEx7/hn4BuV+WON75iAViSUJLiU3PKbpA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz", + "integrity": "sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==", "requires": { - "hyphenate-style-name": "^1.0.2", - "isobject": "^3.0.1" + "hyphenate-style-name": "^1.0.3" } }, "css-mediaquery": { @@ -19409,9 +19667,9 @@ } }, "expo": { - "version": "46.0.16", - "resolved": "https://registry.npmjs.org/expo/-/expo-46.0.16.tgz", - "integrity": "sha512-lZETkf3t+gbZjKjSceIpU7I8Rmm5nZ0ZG1WPzNBBbm+k64/+kKV96s6RqS37W1TTDpIbd+AucT9kKpvtv0JB2A==", + "version": "46.0.17", + "resolved": "https://registry.npmjs.org/expo/-/expo-46.0.17.tgz", + "integrity": "sha512-rB+KMvjU3lFMkec5LcVFFn0Q2iJUEIoyB9TckKMirA15H5mW4yZMao0ilR7239fJ5ytVoDC8SIf7ZAvTmiMuMw==", "requires": { "@babel/runtime": "^7.14.0", "@expo/cli": "0.3.2", @@ -19426,7 +19684,7 @@ "expo-font": "~10.2.1", "expo-keep-awake": "~10.2.0", "expo-modules-autolinking": "0.10.3", - "expo-modules-core": "0.11.8", + "expo-modules-core": "0.11.9", "fbemitter": "^3.0.0", "getenv": "^1.0.0", "invariant": "^2.2.4", @@ -19443,17 +19701,36 @@ "requires": {} }, "expo-asset": { - "version": "8.6.1", - "resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-8.6.1.tgz", - "integrity": "sha512-urbUp1YtwH2J0Qc3inGQJdqTjWKML77SeMNgff+iR9MUE8gDkFqSCDjrBi7i5Oj5DDtq43mmtDg8G8ei6Vchcg==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-8.6.2.tgz", + "integrity": "sha512-XqlXjkuUCEiojbHwbHPjQs1oboRz6w3eV96+9NBD+wb3EUqgAAYY2Do+IWyVCAl8UIFbFi3xzMiqk0Xm9+H8uQ==", "requires": { "blueimp-md5": "^2.10.0", - "expo-constants": "~13.2.2", - "expo-file-system": "~14.1.0", + "expo-constants": "~14.0.0", + "expo-file-system": "~15.1.0", "invariant": "^2.2.4", "md5-file": "^3.2.3", "path-browserify": "^1.0.0", "url-parse": "^1.5.9" + }, + "dependencies": { + "expo-constants": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-14.0.2.tgz", + "integrity": "sha512-wzV3nrzTXTI8yG0tfas3fnqCfKV6YE+1GphEREyVDAShEB6mBInX1b6HgtpHFy2wOtnml+lPVmTCeGtjjLnZhA==", + "requires": { + "@expo/config": "~7.0.2", + "uuid": "^3.3.2" + } + }, + "expo-file-system": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-15.1.1.tgz", + "integrity": "sha512-MYYDKxjLo9VOkvGHqym5EOAUS+ero9O66X5zI+EXJzqNznKvnfScdXeeAaQzShmWtmLkdVDCoYFGOaTvTA1wTQ==", + "requires": { + "uuid": "^3.4.0" + } + } } }, "expo-constants": { @@ -19521,9 +19798,9 @@ } }, "expo-keep-awake": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-10.2.0.tgz", - "integrity": "sha512-kIRtO4Hmrvxh4E45IPWG/NiUZsuRe1AQwBT09pq+kx8nm6tUS4B9TeL6+1NFy+qVBLbGKDqoQD5Ez7XYTFtBeQ==", + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-10.2.1.tgz", + "integrity": "sha512-UBge1BwzDPhUFX0gKu9eDLwEFj4LGiqrOogNoEYxcosM1SwhkbWwPrd3zZtl53LLz02TxEi/CI/MUGJJsrVQLw==", "requires": {} }, "expo-modules-autolinking": { @@ -19609,9 +19886,9 @@ } }, "expo-modules-core": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-0.11.8.tgz", - "integrity": "sha512-goC2ghZFVaV6nXEbk+kz9oKnQmqW8fHVUCSPxC0QXhV0ay1dA9Ki6qqMPagkBJUPAz89NsNqW3bYR6DFXq7lvA==", + "version": "0.11.9", + "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-0.11.9.tgz", + "integrity": "sha512-6AlOE4KHN3/WWbY8hH7W6ceuIFj0qbk1N+UhmMhiCEUas3NvXA6wcH3xjO+8JZ+BRcIB9M4QEeX72j6vDDuExg==", "requires": { "compare-versions": "^3.4.0", "invariant": "^2.2.4" @@ -19671,9 +19948,9 @@ } }, "expo-status-bar": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-1.4.0.tgz", - "integrity": "sha512-vh98g8qMIjig/2XTBsoAWS6Vo2dIIwDWjB3/GiuZ9Lazpxc9GO/APfJ4dar7MibzIDUKIrjotrcL6rLdPH13Ew==" + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-1.4.2.tgz", + "integrity": "sha512-ZWjO6D4ARGYfAd3SWDD3STNudHDhyBZDZjhhseqoEmsf7bS9ykny8KKOhlzJW24qIQNPhkgdvHhaw9fQwMJy3Q==" }, "expo-web-browser": { "version": "11.0.0", @@ -19752,6 +20029,11 @@ "micromatch": "^4.0.4" } }, + "fast-loops": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/fast-loops/-/fast-loops-1.1.3.tgz", + "integrity": "sha512-8EZzEP0eKkEEVX+drtd9mtuQ+/QrlfW/5MlwcwK5Nds6EkZ/tRzEexkzUY2mIssnAyVLT+TKHuRXmFNNXYUd6g==" + }, "fastq": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", @@ -20088,13 +20370,6 @@ "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==", "requires": { "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" - } } }, "has": { @@ -20258,9 +20533,9 @@ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==" + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.1.tgz", + "integrity": "sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==" }, "image-size": { "version": "0.6.3", @@ -20318,11 +20593,12 @@ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "inline-style-prefixer": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-6.0.1.tgz", - "integrity": "sha512-AsqazZ8KcRzJ9YPN1wMH2aNM7lkWQ8tSPrW5uDk1ziYwiAPWSZnUsC7lfZq+BDqLqz0B4Pho5wscWcJzVvRzDQ==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-6.0.4.tgz", + "integrity": "sha512-FwXmZC2zbeeS7NzGjJ6pAiqRhXR0ugUShSNb6GApMl6da0/XGc4MOJsoWAywia52EEWbXNSy0pzkwz/+Y+swSg==", "requires": { - "css-in-js-utils": "^2.0.0" + "css-in-js-utils": "^3.1.0", + "fast-loops": "^1.1.3" } }, "internal-ip": { @@ -21459,6 +21735,52 @@ "graceful-fs": "^4.1.6" } }, + "metro-react-native-babel-preset": { + "version": "0.70.3", + "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.70.3.tgz", + "integrity": "sha512-4Nxc1zEiHEu+GTdEMEsHnRgfaBkg8f/Td3+FcQ8NTSvs+xL3LBrQy6N07idWSQZHIdGFf+tTHvRfSIWLD8u8Tg==", + "requires": { + "@babel/core": "^7.14.0", + "@babel/plugin-proposal-async-generator-functions": "^7.0.0", + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-export-default-from": "^7.0.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/plugin-proposal-optional-catch-binding": "^7.0.0", + "@babel/plugin-proposal-optional-chaining": "^7.0.0", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/plugin-syntax-export-default-from": "^7.0.0", + "@babel/plugin-syntax-flow": "^7.2.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-syntax-optional-chaining": "^7.0.0", + "@babel/plugin-transform-arrow-functions": "^7.0.0", + "@babel/plugin-transform-async-to-generator": "^7.0.0", + "@babel/plugin-transform-block-scoping": "^7.0.0", + "@babel/plugin-transform-classes": "^7.0.0", + "@babel/plugin-transform-computed-properties": "^7.0.0", + "@babel/plugin-transform-destructuring": "^7.0.0", + "@babel/plugin-transform-exponentiation-operator": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0", + "@babel/plugin-transform-function-name": "^7.0.0", + "@babel/plugin-transform-literals": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.0.0", + "@babel/plugin-transform-parameters": "^7.0.0", + "@babel/plugin-transform-react-display-name": "^7.0.0", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/plugin-transform-react-jsx-self": "^7.0.0", + "@babel/plugin-transform-react-jsx-source": "^7.0.0", + "@babel/plugin-transform-runtime": "^7.0.0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0", + "@babel/plugin-transform-spread": "^7.0.0", + "@babel/plugin-transform-sticky-regex": "^7.0.0", + "@babel/plugin-transform-template-literals": "^7.0.0", + "@babel/plugin-transform-typescript": "^7.5.0", + "@babel/plugin-transform-unicode-regex": "^7.0.0", + "@babel/template": "^7.0.0", + "react-refresh": "^0.4.0" + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -21592,9 +21914,9 @@ } }, "metro-react-native-babel-preset": { - "version": "0.70.3", - "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.70.3.tgz", - "integrity": "sha512-4Nxc1zEiHEu+GTdEMEsHnRgfaBkg8f/Td3+FcQ8NTSvs+xL3LBrQy6N07idWSQZHIdGFf+tTHvRfSIWLD8u8Tg==", + "version": "0.72.3", + "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.72.3.tgz", + "integrity": "sha512-uJx9y/1NIqoYTp6ZW1osJ7U5ZrXGAJbOQ/Qzl05BdGYvN1S7Qmbzid6xOirgK0EIT0pJKEEh1s8qbassYZe4cw==", "requires": { "@babel/core": "^7.14.0", "@babel/plugin-proposal-async-generator-functions": "^7.0.0", @@ -21649,6 +21971,54 @@ "metro-react-native-babel-preset": "0.70.3", "metro-source-map": "0.70.3", "nullthrows": "^1.1.1" + }, + "dependencies": { + "metro-react-native-babel-preset": { + "version": "0.70.3", + "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.70.3.tgz", + "integrity": "sha512-4Nxc1zEiHEu+GTdEMEsHnRgfaBkg8f/Td3+FcQ8NTSvs+xL3LBrQy6N07idWSQZHIdGFf+tTHvRfSIWLD8u8Tg==", + "requires": { + "@babel/core": "^7.14.0", + "@babel/plugin-proposal-async-generator-functions": "^7.0.0", + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-export-default-from": "^7.0.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/plugin-proposal-optional-catch-binding": "^7.0.0", + "@babel/plugin-proposal-optional-chaining": "^7.0.0", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/plugin-syntax-export-default-from": "^7.0.0", + "@babel/plugin-syntax-flow": "^7.2.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-syntax-optional-chaining": "^7.0.0", + "@babel/plugin-transform-arrow-functions": "^7.0.0", + "@babel/plugin-transform-async-to-generator": "^7.0.0", + "@babel/plugin-transform-block-scoping": "^7.0.0", + "@babel/plugin-transform-classes": "^7.0.0", + "@babel/plugin-transform-computed-properties": "^7.0.0", + "@babel/plugin-transform-destructuring": "^7.0.0", + "@babel/plugin-transform-exponentiation-operator": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0", + "@babel/plugin-transform-function-name": "^7.0.0", + "@babel/plugin-transform-literals": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.0.0", + "@babel/plugin-transform-parameters": "^7.0.0", + "@babel/plugin-transform-react-display-name": "^7.0.0", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/plugin-transform-react-jsx-self": "^7.0.0", + "@babel/plugin-transform-react-jsx-source": "^7.0.0", + "@babel/plugin-transform-runtime": "^7.0.0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0", + "@babel/plugin-transform-spread": "^7.0.0", + "@babel/plugin-transform-sticky-regex": "^7.0.0", + "@babel/plugin-transform-template-literals": "^7.0.0", + "@babel/plugin-transform-typescript": "^7.5.0", + "@babel/plugin-transform-unicode-regex": "^7.0.0", + "@babel/template": "^7.0.0", + "react-refresh": "^0.4.0" + } + } } }, "metro-resolver": { @@ -22537,9 +22907,9 @@ "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==" }, "postcss": { - "version": "8.4.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz", - "integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==", + "version": "8.4.19", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.19.tgz", + "integrity": "sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==", "requires": { "nanoid": "^3.3.4", "picocolors": "^1.0.0", @@ -22616,9 +22986,9 @@ } }, "postcss-selector-parser": { - "version": "6.0.10", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", - "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", + "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", "requires": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -22953,6 +23323,12 @@ "react-native-iphone-x-helper": "^1.0.3" } }, + "react-native-pager-view": { + "version": "5.4.24", + "resolved": "https://registry.npmjs.org/react-native-pager-view/-/react-native-pager-view-5.4.24.tgz", + "integrity": "sha512-dRMB7i3B+mu4NCeIN6gqbR/kC/rr2wzqO0gisXDdJwJr78G24sWoTNpLEDFo3G8TFHY9nTMutVl5CUvkN2dp6g==", + "requires": {} + }, "react-native-paper": { "version": "4.12.5", "resolved": "https://registry.npmjs.org/react-native-paper/-/react-native-paper-4.12.5.tgz", @@ -23056,6 +23432,12 @@ "prop-types": "^15.5.8" } }, + "react-native-star-rating-widget": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/react-native-star-rating-widget/-/react-native-star-rating-widget-1.5.0.tgz", + "integrity": "sha512-dZUD38h47RvQtMXjjiNMZSjww2r28QRQ5QAQl7wo8+mxwILoDu3Fznom+rSVDjOQ5S2En5wuNqSQ801tr9Dx+w==", + "requires": {} + }, "react-native-svg": { "version": "12.3.0", "resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-12.3.0.tgz", @@ -23065,6 +23447,14 @@ "css-tree": "^1.0.0-alpha.39" } }, + "react-native-tab-view": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/react-native-tab-view/-/react-native-tab-view-3.3.2.tgz", + "integrity": "sha512-s0xr+wiMBHdjsWgbPTyZemgv7jJ+zKPBw/MIQIlKAMo4VCNV1vAZEbOHaHpGbqgYFwsmFXjKZNXQ5UJAIJXlDQ==", + "requires": { + "use-latest-callback": "^0.1.5" + } + }, "react-native-vector-icons": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-9.2.0.tgz", @@ -23267,11 +23657,6 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" } } }, @@ -23289,14 +23674,14 @@ } }, "regenerator-runtime": { - "version": "0.13.10", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz", - "integrity": "sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==" + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, "regenerator-transform": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.0.tgz", - "integrity": "sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==", + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", + "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", "requires": { "@babel/runtime": "^7.8.4" } @@ -23311,16 +23696,16 @@ } }, "regexpu-core": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.1.tgz", - "integrity": "sha512-HrnlNtpvqP1Xkb28tMhBUO2EbyUHdQlsnlAhzWcwHy8WJR53UWr7/MAvqrsQKMbV4qdpv03oTMG8iIhfsPFktQ==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz", + "integrity": "sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==", "requires": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.1.0", "regjsgen": "^0.7.1", "regjsparser": "^0.9.1", "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.0.0" + "unicode-match-property-value-ecmascript": "^2.1.0" } }, "regjsgen": { @@ -24154,9 +24539,9 @@ "integrity": "sha512-EBNuMVSxpssuFcJq/c4zmZ4tpCyX9E27hz5xPJhw4URjRHcYXPHh8rDHY/tJsw5gtP0+tIL3IBYeQVIYjdZFhg==" }, "sucrase": { - "version": "3.28.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.28.0.tgz", - "integrity": "sha512-TK9600YInjuiIhVM3729rH4ZKPOsGeyXUwY+Ugu9eilNbdTFyHr6XcAGYbRVZPDgWj6tgI7bx95aaJjHnbffag==", + "version": "3.29.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.29.0.tgz", + "integrity": "sha512-bZPAuGA5SdFHuzqIhTAqt9fvNEo9rESqXIG3oiKdF8K4UmkQxC4KlNL3lVyAErXp+mPvUqZ5l13qx6TrDIGf3A==", "requires": { "commander": "^4.0.0", "glob": "7.1.6", @@ -24216,9 +24601,9 @@ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" }, "tailwindcss": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.2.tgz", - "integrity": "sha512-c2GtSdqg+harR4QeoTmex0Ngfg8IIHNeLQH5yr2B9uZbZR1Xt1rYbjWOWTcj3YLTZhrmZnPowoQDbSRFyZHQ5Q==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.4.tgz", + "integrity": "sha512-AhwtHCKMtR71JgeYDaswmZXhPcW9iuI9Sp2LvZPo9upDZ7231ZJ7eA9RaURbhpXGVlrjX4cFNlB4ieTetEb7hQ==", "requires": { "arg": "^5.0.2", "chokidar": "^3.5.3", @@ -24478,9 +24863,9 @@ "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" }, "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" }, "type-fest": { "version": "0.12.0", @@ -24543,9 +24928,9 @@ } }, "unicode-match-property-value-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", - "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==" }, "unicode-property-aliases-ecmascript": { "version": "2.1.0", diff --git a/package.json b/package.json index 3f9be67..f85769b 100644 --- a/package.json +++ b/package.json @@ -35,13 +35,16 @@ "react-native-dynamic-search-bar": "github:WrathChaos/react-native-dynamic-search-bar#expo", "react-native-gesture-handler": "~2.5.0", "react-native-keyboard-aware-scroll-view": "^0.9.5", + "react-native-pager-view": "5.4.24", "react-native-paper": "^4.12.5", "react-native-popup-menu": "^0.16.1", "react-native-reanimated": "^2.12.0", "react-native-safe-area-context": "4.3.1", "react-native-screens": "~3.15.0", "react-native-slick": "^1.6.0", + "react-native-star-rating-widget": "^1.5.0", "react-native-svg": "12.3.0", + "react-native-tab-view": "^3.3.2", "react-native-web": "~0.18.7", "react-native-webview": "11.23.0", "react-navigation": "^4.4.4" diff --git a/src/components/CustomButton.tsx b/src/components/CustomButton.tsx index 27b00e3..b1891ba 100644 --- a/src/components/CustomButton.tsx +++ b/src/components/CustomButton.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { Text, TouchableOpacity } from "react-native"; +import { Text, TouchableOpacity, View } from "react-native"; export type Props = { onPress: any; diff --git a/src/components/Navigation/SideMenu.tsx b/src/components/Navigation/SideMenu.tsx index 46e7db7..de2af60 100644 --- a/src/components/Navigation/SideMenu.tsx +++ b/src/components/Navigation/SideMenu.tsx @@ -139,6 +139,7 @@ export default function SideMenu() { component={Login} options={{ headerTintColor: "#fff", + title: "Iniciar sesión", headerTitle: "Ingresar", drawerLabelStyle: dark ? { color: "white" } : null, headerStyle: { @@ -157,6 +158,7 @@ export default function SideMenu() { options={{ headerTintColor: "#fff", headerTitle: "Registro", + title: "Registrarme", drawerLabelStyle: dark ? { color: "white" } : null, headerStyle: { backgroundColor: "#0c35c5", @@ -215,7 +217,7 @@ export default function SideMenu() { <Drawer.Screen name="Notification" options={{ - headerTitle: "", + headerTitle: "Nuevos productos!!", headerTintColor: "#fff", headerStyle: { backgroundColor: "#0c35c5", @@ -295,7 +297,7 @@ export default function SideMenu() { }, drawerItemStyle: { display: "none" }, headerLeft: (focus) => ( - <TouchableOpacity onPress={() => navigation.goBack()}> + <TouchableOpacity onPress={() => navigation.goBack(null)}> <ArrowLeft size={24} style={{ padding: 10, marginLeft: 10 }} color={focus ? "#fff" : "grey"} /> </TouchableOpacity> ), @@ -334,7 +336,7 @@ export default function SideMenu() { backgroundColor: "#0c35c5", }, headerLeft: (focus) => ( - <TouchableOpacity onPress={() => navigation.navigate("Purchases") as never}> + <TouchableOpacity onPress={() => navigation.navigate("Perfil") as never}> <ArrowLeft size={24} style={{ padding: 10, marginLeft: 10 }} color={focus ? "#fff" : "grey"} /> </TouchableOpacity> ), diff --git a/src/screens/Home.tsx b/src/screens/Home.tsx index dda76e7..904271e 100644 --- a/src/screens/Home.tsx +++ b/src/screens/Home.tsx @@ -19,15 +19,20 @@ export default function Home() { const [searchText, setSearchText] = useState(""); const [loading, setLoading] = useState(false); const [onEnd, setOnEnd] = useState(false); - - //const [page, setPage] = useState(0); - let [shoppingPost, setShoppingPost] = useState<TShoppingPost[] | undefined>(undefined); const [aux, setAux] = useState<TShoppingPost[] | undefined>(undefined); const { colorScheme } = useColorScheme(); let dark = colorScheme === "dark"; + useEffect(() => { + const unsubscribe = nav.addListener("blur", () => { + setShoppingPost(undefined); + setAux([]); + }); + return unsubscribe; + }, [nav]); + useEffect(() => { const getInitialData = async () => { const email = await getData("email"); @@ -36,7 +41,7 @@ export default function Home() { .then((res) => { if (res.status === 200) { let posts = res.data as TShoppingPost[]; - let notMyPosts = posts.filter((p) => p.sellerEmail !== email); + let notMyPosts = posts.filter((p) => p.sellerEmail !== email && p.shoppingPostStatus !== "PAUSED"); setShoppingPost(notMyPosts); } }) @@ -89,15 +94,33 @@ export default function Home() { } return ( <> - <View className="bg-[#fff] dark:bg-dark-mode-bg border-[1.22px] border-[#0c35c5] m-3 p-1"> - <Card - containerStyle={ - dark - ? { backgroundColor: "#292626", borderColor: "#292626", borderRadius: 0, borderWidth: 0 } - : { backgroundColor: "white", borderColor: "white", elevation: 5, marginBottom: 4 } - } - > - <TouchableOpacity onPress={() => handlePress(data)}> + <TouchableOpacity onPress={() => handlePress(data)}> + <View className="bg-[#fff] dark:bg-dark-mode-bg border-[1.22px] border-[#0c35c5] m-3 p-1"> + <Card + containerStyle={ + dark + ? { + backgroundColor: "#292626", + borderColor: "#554b4b", + elevation: 10, + marginBottom: 4, + borderWidth: 1, + shadowRadius: 10, + shadowColor: "#aaeeda", + shadowOpacity: 0.3, + } + : { + backgroundColor: "white", + borderColor: "white", + elevation: 10, + marginBottom: 4, + borderWidth: 2, + shadowRadius: 10, + shadowColor: "#0c35c5", + shadowOpacity: 0.3, + } + } + > <Card.Title className="dark:text-dark-mode-text"> {data.title} </Card.Title> <Card.Divider className="fill-gray-900" /> <Card.Image @@ -117,30 +140,31 @@ export default function Home() { : { uri: `data:image/jpg;base64,${data.base64Images[randomIndex]}` } } /> - </TouchableOpacity> - <Card.Divider className="m-3 fill-gray-900" /> - <View className="flex-row justify-between"> - <View className="flex-row"> - <Text className="font-semibold text-[18px] dark:text-dark-mode-text my-auto"> - {"USD " + data.price} - </Text> - {data.onSale ? ( - <Text className="font-bold dark:text-[#0f0] text-[#0e994d] ml-2">{"% " + data.saleDiscount}</Text> + + <Card.Divider className="m-3 fill-gray-900" /> + <View className="flex-row justify-between"> + <View className="flex-row"> + <Text className="font-semibold text-[18px] dark:text-dark-mode-text my-auto"> + {"USD " + data.price} + </Text> + {data.onSale ? ( + <Text className="font-bold dark:text-[#0f0] text-[#0e994d] ml-2">{"% " + data.saleDiscount}</Text> + ) : ( + "" + )} + </View> + {data.hasDelivery ? ( + <View className="flex-row items-center justify-center"> + <Text className="p-1 font-semibold text-[18px] dark:text-dark-mode-text">Delivery</Text> + <Truck size={20} color={dark ? "white" : "black"} /> + </View> ) : ( "" )} </View> - {data.hasDelivery ? ( - <View className="flex-row items-center justify-center"> - <Text className="p-1 font-semibold text-[18px] dark:text-dark-mode-text">Delivery</Text> - <Truck size={20} color={dark ? "white" : "black"} /> - </View> - ) : ( - "" - )} - </View> - </Card> - </View> + </Card> + </View> + </TouchableOpacity> </> ); }; @@ -177,10 +201,10 @@ export default function Home() { if (res.status === 200) { let k: TShoppingPost[] = res.data; - if (aux) { + /* if (aux) { // es busqueda, si no encuentra items en su lista deberia ir a buscar mas a la bd console.log(aux[0].title); - } + }*/ if (k.length === shoppingPost?.length) { setOnEnd(true); @@ -188,10 +212,22 @@ export default function Home() { } else if (k.length > shoppingPost!.length) { let arr = k.splice(shoppingPost!.length, k.length); let notMyPosts = arr.filter((p) => p.sellerEmail !== email); - setShoppingPost([...shoppingPost!, ...notMyPosts]); + notMyPosts.forEach((p) => { + if (shoppingPost?.find((x) => x.id === p.id) === undefined) { + setShoppingPost([...shoppingPost!, ...notMyPosts]); + } + }); + setOnEnd(true); setLoading(false); } else if (k.length < shoppingPost!.length) { + let w = shoppingPost; + w?.forEach((xw) => { + if (!k.includes(xw)) { + w?.splice(w.indexOf(xw), 1); + } + }); + setShoppingPost(w); } } }) diff --git a/src/screens/Login.tsx b/src/screens/Login.tsx index d7060f6..8d8bc54 100644 --- a/src/screens/Login.tsx +++ b/src/screens/Login.tsx @@ -66,6 +66,8 @@ export default function Login() { Alert.alert("Credenciales incorrectas, verifique"); else if (err.response.status === 400 && err.response.data.error_description === "Account is not fully set up") Alert.alert("Verifique su cuenta, gracias"); + else if (err.response.status === 400 && err.response.data.error_description === "Account disabled") + Alert.alert("Cuenta bloqueada. Contacte a los administradores."); else Alert.alert("Problema interno, intente luego"); } else Alert.alert("Problema interno, intente luego"); }) diff --git a/src/screens/ShoppingPost.tsx b/src/screens/ShoppingPost.tsx index 215c152..ea84daa 100644 --- a/src/screens/ShoppingPost.tsx +++ b/src/screens/ShoppingPost.tsx @@ -8,8 +8,7 @@ import CustomReport, { ReportIOS } from "../components/Report/CustomReport"; import Loading from "../components/Loading"; import { TShoppingPost } from "../../urubuy"; import { Package, ShoppingCartSimple } from "phosphor-react-native"; -import StarSvg from "../components/Svgs/StarSvg"; -import { useColorScheme } from "nativewind"; +import { StarRatingDisplay } from "react-native-star-rating-widget"; type SellerRating = { username: string; @@ -22,8 +21,6 @@ export default function ShoppingPost(props: any) { const [promptAndroid, setPromptAndroid] = useState(false); const [activeUser, setActiveUser] = useState<string | undefined>(undefined); const [seller, setSeller] = useState<SellerRating | undefined>(undefined); - const { colorScheme } = useColorScheme(); - const dark = colorScheme === "dark"; useEffect(() => { const unsubscribe = nav.addListener("blur", () => { @@ -76,7 +73,7 @@ export default function ShoppingPost(props: any) { function handleShowSeller(email: string) { getSellerProfile(email).then((res) => { if (res.status === 200) { - setSeller({ username: res.data.username, averageRating: res.data.averageRating }); + setSeller({ username: res.data.username, averageRating: Math.floor(res.data.averageRating) }); } }); } @@ -98,20 +95,21 @@ export default function ShoppingPost(props: any) { <ScrollView showsVerticalScrollIndicator={false}> <View className="flex-row items-center justify-between"> <TouchableOpacity onPress={() => handleProfile(shoppingPost.sellerEmail)}> - <Text className="text-center font-bold text-[19px] mt-2 ml-5 text-[#cf8c40]">{seller?.username!}</Text> + <Text className="text-center font-bold text-[19px] mt-2 ml-5 text-gold-buy">{seller?.username!}</Text> </TouchableOpacity> <TouchableOpacity className={Platform.OS === "android" ? "mr-3" : ""} onPress={() => alert("todo: calificaciones del seller")} > - <Text className="text-center font-bold text-[19px] mt-2 text-[#cf8c40] scale-[.65]"> - {[...Array(seller?.averageRating)].map((i, k) => ( - <View key={k}> - <StarSvg color={"#f1c533"} /> - </View> - ))} - </Text> + <View className="mt-2 mr-5"> + <StarRatingDisplay + rating={seller?.averageRating ? seller?.averageRating : 1} + starStyle={{ marginHorizontal: -2 }} + color="#cf8c40" + starSize={23} + /> + </View> </TouchableOpacity> </View> <SliderSlick pictures={shoppingPost.base64Images !== null ? shoppingPost.base64Images : []} /> @@ -122,7 +120,7 @@ export default function ShoppingPost(props: any) { shoppingPost.onSale && !shoppingPost.hasDelivery ? "flex-row items-center justify-center" : "flex-row" } > - <Text className="font-bold text-[17px] mt-2 ml-7 text-[#cf8c40]"> + <Text className="font-bold text-[17px] mt-2 ml-7 text-gold-buy"> EN OFERTA!! {"%" + shoppingPost.saleDiscount} </Text> </View> @@ -160,7 +158,7 @@ export default function ShoppingPost(props: any) { ) : null} </View> - <View className="h-auto w-[96%] bg- ml-[2%] rounded-3xl border-2 border-[#cf8c40] border-opacity-85"> + <View className="h-auto w-[96%] bg- ml-[2%] rounded-3xl border-2 border-gold-buy border-opacity-85"> <View className="flex-row justify-between"> <Text className="mt-3 p-3 font-bold text-[17px] text-dark-mode-text">Descripción del producto</Text> <Text className="mt-3 p-3 font-bold text-[17px] text-dark-mode-text"> @@ -170,17 +168,22 @@ export default function ShoppingPost(props: any) { <Text className="flex-wrap mt-3 p-3 font-semibold text-[17px] text-dark-mode-text"> {shoppingPost.description} </Text> + <TouchableOpacity className={Platform.OS === "android" ? "ml-5" : ""} onPress={() => alert("todo: calificaciones del producto")} > - <Text className="text-left font-bold text-[19px] mt-2 text-[#cf8c40] scale-[.65]"> - {[...Array(shoppingPost?.averageRating)].map((i, k) => ( - <View key={k}> - <StarSvg color={"#f1c533"} /> - </View> - ))} - </Text> + <View className="flex-row mt-2 ml-5"> + <StarRatingDisplay + rating={shoppingPost?.averageRating ? shoppingPost?.averageRating : 1} + starStyle={{ marginHorizontal: -2 }} + color="#cf8c40" + starSize={23} + /> + <Text className="font-semibold mt-1 ml-2 text-[17px] text-dark-mode-text"> + {Math.floor(Math.random() * Math.max(shoppingPost?.averageRating!, 10))} + </Text> + </View> </TouchableOpacity> </View> diff --git a/src/screens/SignUp.tsx b/src/screens/SignUp.tsx index 3077b27..af9dc43 100644 --- a/src/screens/SignUp.tsx +++ b/src/screens/SignUp.tsx @@ -254,8 +254,9 @@ export default function SignUp() { <Image source={{ uri: `data:image/jpg;base64,${image}` }} style={{ width: 200, height: 200 }} /> </View> )} - - <CustomButton isDisabled={!validPasswords} onPress={handleRegister} value="SignUp" style={{}} /> + <View className="mt-3"> + <CustomButton isDisabled={!validPasswords} onPress={handleRegister} value="Registrarme" style={{}} /> + </View> </ScrollView> </KeyboardAvoidingView> </> diff --git a/src/screens/UserProfile.tsx b/src/screens/UserProfile.tsx index 6fba099..bfd3453 100644 --- a/src/screens/UserProfile.tsx +++ b/src/screens/UserProfile.tsx @@ -1,16 +1,21 @@ import React, { useEffect, useState } from "react"; -import { Text, View, Image, Alert } from "react-native"; +import { Text, View, Image, Alert, FlatList } from "react-native"; import { getCustomerProfile, getSellerProfile } from "../services/Requests"; -import StarSvg from "../components/Svgs/StarSvg"; import { useNavigation } from "@react-navigation/core"; import Loading from "../components/Loading"; import { useColorScheme } from "nativewind"; -import { TSeller, TCustomer } from "../../urubuy"; +import { TSeller, TCustomer, TUserReview } from "../../urubuy"; +import { StarRatingDisplay } from "react-native-star-rating-widget"; +import CustomButton from "../components/CustomButton"; +import { Star } from "phosphor-react-native"; +import { Divider } from "react-native-paper"; +import { Card } from "@rneui/themed"; function UserProfile(props: any) { const [seller, setSeller] = useState<TSeller | undefined>(undefined); const [customer, setCustomer] = useState<TCustomer | undefined>(undefined); - + const [showReviews, setShowReviews] = useState(false); + const [reviews, setReviews] = useState<TUserReview[] | undefined>(undefined); const nav = useNavigation(); const [loading, setLoading] = useState(false); const { colorScheme } = useColorScheme(); @@ -18,7 +23,9 @@ function UserProfile(props: any) { useEffect(() => { const unsuscribe = nav.addListener("focus", () => { + setReviews([]); getInitialData(); + setShowReviews(false); }); return unsuscribe; }, [props]); @@ -31,7 +38,8 @@ function UserProfile(props: any) { if (res.status === 200) { let myUser: TSeller = res.data; setSeller(myUser); - } else console.error("getting s profile"); + setReviews(myUser.receivedUserReviews); + } else console.error("err getting s profile"); }) .catch((err) => { console.log(err.response.data); @@ -41,7 +49,8 @@ function UserProfile(props: any) { if (res.status === 200) { let myUser: TCustomer = res.data; setCustomer(myUser); - } else console.error("getting c profile"); + setReviews(myUser.receivedUserReviews); + } else console.error("err getting c profile"); }) .catch((err) => { console.log(err.response.data); @@ -74,7 +83,6 @@ function UserProfile(props: any) { className="w-[150px] h-[250px] ml-3" /> )} - <View className="max-h-[250px] max-w-[250px] absolute top-[70] left-[160] border-[black]"> <Text className="text-[black] dark:text-dark-mode-text text-[20px] font-semibold ml-[15px]"> {(user as TSeller) ? (user as TSeller).firstName + " " + (user as TSeller).lastName : null} @@ -82,15 +90,95 @@ function UserProfile(props: any) { <Text className="text-[black] dark:text-dark-mode-text text-[15px] font-semibold ml-[15px] mt-[15px] p-[1]"> {user?.email} </Text> - - <View className="flex-row m-[10px] p-[2]"> - {[...Array(user?.averageRating)].map((i, k) => ( - <View key={k}> - <StarSvg color={dark ? "#f1c533" : "#0c35c5"} /> - </View> - ))} + <View className="mt-3 ml-4"> + <StarRatingDisplay + rating={seller?.averageRating ? seller?.averageRating : 1} + starStyle={{ marginHorizontal: -2 }} + color={dark ? "#cf8c40" : "blue"} + /> </View> </View> + + <CustomButton + onPress={() => setShowReviews(!showReviews)} + value={"Ver calificaciones"} + style={undefined} + isDisabled={false} + /> + <View className="left-[72px] bottom-7"> + <Star size={20} color="white" weight="duotone" /> + </View> + </> + ); + }; + + const _renderItem = ({ item }: { item: TUserReview }) => <ListItem data={item} />; + + const _keyExtractor = (item: TUserReview) => String(item.id); + + const _header = () => { + return ( + <Text className="text-[#000] mx-auto dark:text-dark-mode-text text-[20px] font-semibold mt-[15px]"> + Calificaciones + </Text> + ); + }; + + const _separator = () => { + return <Divider style={{ padding: 1.13, backgroundColor: "white" }} />; + }; + + type ScrollList = { + data: TUserReview; + }; + + const ListItem: React.FC<ScrollList> = ({ data }) => { + return ( + <> + <View className="bg-[#fff] dark:bg-dark-mode-bg border-[1.22px] border-header-color dark:border-gold-buy m-3 p-1"> + <Card + containerStyle={ + dark + ? { + backgroundColor: "#292626", + borderColor: "#554b4b", + elevation: 10, + marginBottom: 4, + borderWidth: 1, + } + : { + backgroundColor: "white", + borderColor: "white", + elevation: 10, + marginBottom: 4, + borderWidth: 2, + shadowRadius: 10, + shadowColor: "#0c35c5", + shadowOpacity: 0.3, + } + } + > + <Card.Title className="text-[#000] dark:text-dark-mode-text"> + <StarRatingDisplay + rating={data.rating ? data.rating : 1} + starStyle={{ marginHorizontal: -2 }} + color={dark ? "#cf8c40" : "#0c35c5"} + starSize={23} + /> + </Card.Title> + <Card.Divider className="fill-gray-900" /> + + <View className="justify-between"> + <Text className="text-[#000] mt-2 dark:text-dark-mode-text text-[18px] font-semibold"> + {data.customerEmail}: + </Text> + <Card.FeaturedSubtitle className="font-semibold text-[18px] p-2 text-[#000] dark:text-dark-mode-text my-auto"> + {data.description} + </Card.FeaturedSubtitle> + <Card.FeaturedSubtitle className="font-semibold text-[18px] dark:text-dark-mode-text my-auto"></Card.FeaturedSubtitle> + </View> + </Card> + </View> </> ); }; @@ -107,6 +195,21 @@ function UserProfile(props: any) { ) : seller ? ( renderProfile(seller) ) : null} + {showReviews ? ( + reviews && reviews.length > 0 ? ( + <FlatList + ItemSeparatorComponent={_separator} + ListHeaderComponent={_header} + data={reviews} + renderItem={_renderItem} + keyExtractor={_keyExtractor} + /> + ) : ( + <Text className="text-[#000] text-center my-auto dark:text-dark-mode-text text-[20px] font-semibold ml-[15px]"> + Usuario no tiene calificaciones. + </Text> + ) + ) : null} </View> </> ); diff --git a/src/screens/customer/Checkout.tsx b/src/screens/customer/Checkout.tsx index 02d1b61..9e6084e 100644 --- a/src/screens/customer/Checkout.tsx +++ b/src/screens/customer/Checkout.tsx @@ -18,7 +18,7 @@ export default function Checkout(props: any) { const nav = useNavigation(); const [errorMessage, setErrorMessage] = useState(""); const [successMessage, setSuccessMessage] = useState(""); - const urlPay = Constants.manifest?.extra?.PAYPAL; + const urlPay = Constants.manifest?.extra?.URL_CLOUD + "paypal/pay/"; const [shoppingCartId, setShoppingCartId] = useState<string | undefined>(""); const [checkout, setCheckout] = useState<TCheckoutResponse | undefined>(undefined); const [loadingRedirect, setLoadingRedirect] = useState(false); diff --git a/src/screens/customer/GiveReview.tsx b/src/screens/customer/GiveReview.tsx index 105593c..ed03bef 100644 --- a/src/screens/customer/GiveReview.tsx +++ b/src/screens/customer/GiveReview.tsx @@ -1,7 +1,7 @@ -import { useFocusEffect } from "@react-navigation/core"; -import { ChatCircleDots, ImageSquare, Star, X, XCircle } from "phosphor-react-native"; +import { useFocusEffect, useNavigation } from "@react-navigation/core"; +import { ChatCircleDots, ImageSquare, PencilSimple, Star, UserCircle, X, XCircle } from "phosphor-react-native"; import React, { useEffect, useState } from "react"; -import { View, Text, TouchableOpacity, Modal, Image, ScrollView, Alert } from "react-native"; +import { View, Text, TouchableOpacity, Modal, Image, ScrollView, Alert, Platform } from "react-native"; import { useColorScheme } from "nativewind"; import * as ImagePicker from "expo-image-picker"; import CustomButton from "../../components/CustomButton"; @@ -10,7 +10,8 @@ import { TReview, TUserReview } from "../../../urubuy"; import { Divider, TextInput } from "react-native-paper"; import Loading from "../../components/Loading"; import myStyle from "../../../assets/styles"; -import { getData, reviewSeller } from "../../services/Requests"; +import { getData, getSellerProfile, reviewSeller } from "../../services/Requests"; +import StarRating from "react-native-star-rating-widget"; type GReview = { titlePhoto: string; @@ -26,19 +27,17 @@ export default function GiveReview(props: any) { const [images, setImages] = useState<string[] | undefined>([]); const [photos, setPhotos] = useState<GReview[] | undefined>([]); const [defaultRating, setDefaultRating] = useState(2); - const [maxRating, setMaxRating] = useState<number[] | undefined>([1, 2, 3, 4, 5]); - const starCorner = require("../../../assets/star_corner.png"); - const starFilled = require("../../../assets/star_filled.png"); - const uriStarCorner = Image.resolveAssetSource(starCorner).uri; - const uriStarFilled = Image.resolveAssetSource(starFilled).uri; const { colorScheme } = useColorScheme(); const dark = colorScheme === "dark"; const [inputHeight, setInputHeight] = useState(0); const [email, setEmail] = useState(""); const [sellerEmail, setSellerEmail] = useState(""); + const [sellerUsername, setSellerUsername] = useState(""); + const nav = useNavigation(); useFocusEffect(() => { setPurchaseId(props.route.params.id); + fetchSellerUsername(props.route.params.seller); setSellerEmail(props.route.params.seller); }); @@ -46,6 +45,14 @@ export default function GiveReview(props: any) { getInitialData(); }, []); + const fetchSellerUsername = async (seller: string) => { + getSellerProfile(seller).then((res) => { + if (res.status === 200) { + setSellerUsername(res.data.username); + } + }); + }; + const getInitialData = async () => { let email = await getData("email"); setEmail(email!); @@ -89,29 +96,6 @@ export default function GiveReview(props: any) { } else setLoading(false); }; - const CustomRatingBar = () => { - return ( - <View className="flex-row justify-center mt-2"> - {maxRating?.map((item, key) => { - return ( - <TouchableOpacity - activeOpacity={0.7} - key={item} - onPress={() => { - setDefaultRating(item); - }} - > - <Image - className="w-8 h-8 mr-5 bg-cover" - source={item <= defaultRating ? { uri: uriStarFilled } : { uri: uriStarCorner }} - /> - </TouchableOpacity> - ); - })} - </View> - ); - }; - let handleReview = () => { if (showReviewSeller === true) { let sellerReview: TUserReview = { @@ -146,24 +130,53 @@ export default function GiveReview(props: any) { customerEmail: email, sellerEmail: sellerEmail, }; - //showReviewProduct(review); } }; + const sellerClicked = () => { + if (sellerEmail) nav.navigate("UserProfile" as never, { email: sellerEmail } as never); + else console.log("seller wrong"); + }; + return ( <> - <View className="items-center justify-center flex-1 h-fit dark:bg-dark-mode-bg"> - <Text className="p-2 text-lg font-semibold dark:text-dark-mode-text"> - COMO CUANDO LLEGABA LA HOJITA DE CALIFICAR PROFES + <View className="flex-1 dark:bg-dark-mode-bg "> + <Text className="mt-5 mr-7 p-2 text-[45px] font-extrabold text-[#000] dark:text-dark-mode-text"> + Calificaciones </Text> - <Text className="p-2 text-lg font-semibold dark:text-dark-mode-text">COMPRA ID: {purchaseId}</Text> - <View className="flex-row-reverse justify-between m-2"> - <TouchableOpacity onPress={handleSeller} className="bg-dark-mode-bg dark:bg-[#504e4e] rounded-3xl ml-2"> - <Text className="p-2 text-lg font-semibold text-dark-mode-text">Calificar vendedor</Text> - </TouchableOpacity> - <TouchableOpacity onPress={handleProduct} className="bg-dark-mode-bg dark:bg-[#504e4e] rounded-3xl"> - <Text className="p-2 text-lg font-semibold text-dark-mode-text">Calificar producto</Text> - </TouchableOpacity> + + <View className="border-header-color dark:border-gold-buy border-[1.33px] p-3 m-2"> + <View className="flex-row"> + <Text className="p-2 text-lg font-semibold dark:text-dark-mode-text">Calificar compra del vendedor:</Text> + <TouchableOpacity className="flex-1" onPress={() => sellerClicked()}> + <Text className="flex-wrap p-2 text-lg font-semibold text-header-color dark:text-gold-buy "> + {sellerUsername} + </Text> + </TouchableOpacity> + </View> + <Text className="p-2 text-lg font-semibold text-center dark:text-dark-mode-text"> + COMPRA ID: {purchaseId} + </Text> + <View className="justify-center m-2"> + <CustomButton + onPress={() => handleProduct()} + value={"Calificar producto"} + style={undefined} + isDisabled={false} + /> + <View className="left-[57px] bottom-7"> + <PencilSimple size={19} color={"white"} weight="duotone" /> + </View> + <CustomButton + onPress={() => handleSeller()} + value={"Calificar vendedor"} + style={undefined} + isDisabled={false} + /> + <View className="left-[57px] bottom-7"> + <UserCircle size={19} color={"white"} weight="duotone" /> + </View> + </View> </View> </View> {showReviewSeller || showReviewProduct ? ( @@ -213,7 +226,7 @@ export default function GiveReview(props: any) { <XCircle size={25} weight="regular" color={colorScheme === "dark" ? "white" : "black"} /> </TouchableOpacity> <Text className="text-lg font-semibold dark:text-dark-mode-text"> - {showReviewProduct ? "Calificar producto" : "Calificar vendedor"} + {showReviewProduct ? "Calificar producto" : `Calificar vendedor: ${sellerEmail}`} </Text> <Divider style={dark ? { height: 2, backgroundColor: "white" } : { height: 2, backgroundColor: "#32377B" }} @@ -228,16 +241,26 @@ export default function GiveReview(props: any) { /> } onChangeText={setReviewComment} - onContentSizeChange={(event) => { - setInputHeight(event.nativeEvent.contentSize.height); - }} + onContentSizeChange={(e) => setInputHeight(e.nativeEvent.contentSize.height)} theme={dark ? { colors: { placeholder: "white", text: "white" } } : {}} - style={[myStyle.textAreaB, { height: Math.max(50, inputHeight) }]} + style={ + dark + ? [myStyle.textAreaB, { height: Math.max(50, inputHeight) }] + : [myStyle.textArea, { height: Math.max(50, inputHeight) }] + } value={reviewComment} /> </View> - <View className="mt-2"> - <CustomRatingBar /> + <View className="flex-row mt-2 text-start"> + <Text className="mt-3 text-lg font-semibold dark:text-dark-mode-text">Calificación: </Text> + <StarRating + starStyle={{ marginHorizontal: -0.5, left: 16, marginTop: 10 }} + rating={defaultRating} + color="#cf8c40" + starSize={32} + minRating={3} + onChange={(n) => setDefaultRating(n)} + /> </View> {showReviewProduct && ( <View className="flex-row mt-"> @@ -283,7 +306,7 @@ export default function GiveReview(props: any) { style={{ width: 130, margin: 10 }} isDisabled={false} /> - <View className={"right-9 top-[25]"}> + <View className={"right-[132px] top-[25px]"}> <X size={20} weight="fill" color="white" /> </View> <CustomButton @@ -292,7 +315,9 @@ export default function GiveReview(props: any) { style={{ width: 130, margin: 10 }} isDisabled={false} /> - <View className={"right-9 top-[25]"}> + <View + className={Platform.OS === "android" ? "right-[135px] top-[26px]" : "right-[132px] top-[24px]"} + > <Star size={20} weight="duotone" color="white" /> </View> </View> diff --git a/src/screens/customer/Help.tsx b/src/screens/customer/Help.tsx index 534e720..13982dd 100644 --- a/src/screens/customer/Help.tsx +++ b/src/screens/customer/Help.tsx @@ -18,7 +18,7 @@ function Help() { return ( <View className="w-full h-full bg-white dark:bg-dark-mode-bg"> - <Text className="mt-8 mr-7 p-2 text-[50px] font-extrabold text-[#000] dark:text-dark-mode-text">Ayuda</Text> + <Text className="mt-8 mr-7 p-2 text-[45px] font-extrabold text-[#000] dark:text-dark-mode-text">Ayuda</Text> <Divider style={dark ? { height: 2, backgroundColor: "white" } : { height: 2, backgroundColor: "#32377B" }} /> <SafeAreaView className="border-[1.33px] rounded-md mt-10 w-[96%] p-3 mx-auto border-[#32377B] dark:border-[#fff]"> <TouchableOpacity diff --git a/src/screens/customer/Profile.tsx b/src/screens/customer/Profile.tsx index 26273d5..a37c832 100644 --- a/src/screens/customer/Profile.tsx +++ b/src/screens/customer/Profile.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useState } from "react"; import { Text, View, Image, TouchableOpacity, Platform, Alert } from "react-native"; -import { getData, getCustomerProfile, updateProfile } from "../../services/Requests"; +import { getData, getCustomerProfile, updateProfile, resetPassword, getIdUsuario } from "../../services/Requests"; import StarSvg from "../../components/Svgs/StarSvg"; import { useFocusEffect, useNavigation } from "@react-navigation/core"; import CustomButton from "../../components/CustomButton"; @@ -9,12 +9,15 @@ import { useColorScheme } from "nativewind"; import { TCustomer } from "../../../urubuy"; import { Menu, MenuTrigger, MenuOptions, MenuOption } from "react-native-popup-menu"; import * as ImagePicker from "expo-image-picker"; +import { StarRatingDisplay } from "react-native-star-rating-widget"; +import Loading from "../../components/Loading"; function Profile() { const [user, setUser] = useState<TCustomer | undefined>(undefined); const nav = useNavigation(); const { colorScheme } = useColorScheme(); const dark = colorScheme === "dark"; + const [loading, setLoading] = useState(false); useFocusEffect(() => { getInitialData(); @@ -39,6 +42,8 @@ function Profile() { addresses: res.data.addresses, picture: res.data.picture, givenUserReviews: res.data.givenUserReviews, + receivedUserReviews: res.data.receivedUserReviews, + purchases: res.data.purchases, }; setUser(myUser); } else console.error("getting profile"); @@ -87,6 +92,36 @@ function Profile() { } }; + const handleResetPassword = () => { + setLoading(true); + getIdUsuario() + .then((res: any) => { + res.data.map((u: any) => { + if (u.email === user?.email.toLocaleLowerCase()) { + let id = u.id; + resetPassword(id) + .then((res) => { + if (res.status === 204) { + Alert.alert("Verifique email para restaurar contraseña"); + setLoading(false); + } else { + setLoading(false); + Alert.alert("Imposible enviar mail"); + } + }) + .catch((er) => { + setLoading(false); + console.log(er); + }); + } + }); + }) + .catch((er) => { + setLoading(false); + console.log(er); + }); + }; + return ( <> <View className="flex-1 dark:bg-dark-mode-bg"> @@ -133,91 +168,101 @@ function Profile() { {user?.email} </Text> - <View className="flex-row m-[10px] p-[2px]"> - {[...Array(user?.averageRating)].map((i, k) => ( - <View key={k}> - <StarSvg color={dark ? "#f1c533" : "#0c35c5"} /> - </View> - ))} - </View> + <StarRatingDisplay + rating={user?.averageRating ? user?.averageRating : 1} + starStyle={{ marginHorizontal: -2, left: 16, marginTop: 10 }} + color={dark ? "#cf8c40" : "#0c35c5"} + starSize={24} + /> </View> - <View className="my-8"> - <TouchableOpacity> - <CustomButton - isDisabled={false} - onPress={() => nav.navigate("Purchases" as never)} - value={"Mis compras"} - style={undefined} - /> - <View - className={Platform.select({ - ios: "absolute left-[85px] mt-6", - android: "absolute left-[70px] mt-[30px]", - })} - > - <Handbag size={26} color="white" /> - </View> - </TouchableOpacity> - - <TouchableOpacity> - <CustomButton - isDisabled={false} - onPress={() => nav.navigate("Reviews" as never, { reviews: user?.givenUserReviews } as never)} - value={"Mis calificaciones"} - style={undefined} - /> - <View - className={Platform.select({ - ios: "absolute left-[85px] mt-6", - android: "absolute left-[70px] mt-[30px]", - })} - > - <Star size={24} color="white" /> - </View> - </TouchableOpacity> - - <TouchableOpacity> - <CustomButton - isDisabled={false} - onPress={() => - nav.navigate( - "Addresses" as never, - { - addresses: user?.addresses, - } as never, - ) - } - value={"Mis direcciones"} - style={undefined} - /> - <View - className={Platform.select({ - ios: "absolute left-[85px] mt-6", - android: "absolute left-[70px] mt-[30px]", - })} - > - <AddressBook size={24} color="white" /> - </View> - </TouchableOpacity> - - <TouchableOpacity> - <CustomButton - isDisabled={false} - onPress={() => Alert.alert("todo: le pide a keycloak")} - value={"Cambiar contraseña"} - style={undefined} - /> - <View - className={Platform.select({ - ios: "absolute left-[85px] mt-6", - android: "absolute left-[70px] mt-[30px]", - })} - > - <WarningOctagon size={24} color="white" /> - </View> - </TouchableOpacity> - </View> + {loading ? ( + <View className="mx-auto my-auto"> + <Loading text="Enviando mail..." bg={true} /> + </View> + ) : ( + <View className="my-8"> + <TouchableOpacity> + <CustomButton + isDisabled={false} + onPress={() => nav.navigate("Purchases" as never, { purchases: user?.purchases } as never)} + value={"Mis compras"} + style={undefined} + /> + <View + className={Platform.select({ + ios: "absolute left-[85px] mt-6", + android: "absolute left-[70px] mt-[30px]", + })} + > + <Handbag size={26} color="white" /> + </View> + </TouchableOpacity> + + <TouchableOpacity> + <CustomButton + isDisabled={false} + onPress={() => { + nav.navigate( + "Reviews" as never, + { givenReviews: user?.givenUserReviews, receivedUserReviews: user?.receivedUserReviews } as never, + ); + }} + value={"Mis calificaciones"} + style={undefined} + /> + <View + className={Platform.select({ + ios: "absolute left-[85px] mt-6", + android: "absolute left-[70px] mt-[30px]", + })} + > + <Star size={24} color="white" /> + </View> + </TouchableOpacity> + + <TouchableOpacity> + <CustomButton + isDisabled={false} + onPress={() => + nav.navigate( + "Addresses" as never, + { + addresses: user?.addresses, + } as never, + ) + } + value={"Mis direcciones"} + style={undefined} + /> + <View + className={Platform.select({ + ios: "absolute left-[85px] mt-6", + android: "absolute left-[70px] mt-[30px]", + })} + > + <AddressBook size={24} color="white" /> + </View> + </TouchableOpacity> + + <TouchableOpacity> + <CustomButton + isDisabled={false} + onPress={() => handleResetPassword()} + value={"Cambiar contraseña"} + style={undefined} + /> + <View + className={Platform.select({ + ios: "absolute left-[85px] mt-6", + android: "absolute left-[70px] mt-[30px]", + })} + > + <WarningOctagon size={24} color="white" /> + </View> + </TouchableOpacity> + </View> + )} </View> </> ); diff --git a/src/screens/customer/Purchase.tsx b/src/screens/customer/Purchase.tsx index 6ddce89..522667b 100644 --- a/src/screens/customer/Purchase.tsx +++ b/src/screens/customer/Purchase.tsx @@ -1,40 +1,25 @@ -import { useNavigation } from "@react-navigation/core"; +import { useFocusEffect, useNavigation } from "@react-navigation/core"; import React, { useEffect, useState } from "react"; import { FlatList, ImageBackground, Image, Text, View, Platform } from "react-native"; import { Divider } from "react-native-paper"; import { useColorScheme } from "nativewind"; import { Star } from "phosphor-react-native"; import CustomButton from "../../components/CustomButton"; -import { TSeller } from "../../../urubuy"; +import { TPurchase, TSeller } from "../../../urubuy"; -type Purchase = { - id: string; - title: string; - description: string; - seller: TSeller; +type PurchaseCard = { + purchase: TPurchase; }; -const myData = [ - { id: 1, date: "20/11/2011", name: "la compra 1", price: "300", seller: "pepitoSeller" }, - { id: 2, date: "21/11/2011", name: "la compra 2", price: "400", seller: "pepitoSeller" }, - { id: 3, date: "10/07/2021", name: "3 la compra", price: "100" }, - { id: 4, date: "10/10/2010", name: "4 la compra", price: "400" }, - { id: 5, date: "11/11/2011", name: "5inho", price: "500" }, -]; - export default function Purchase(props: any) { const nav = useNavigation(); - const [purchases, setPurchases] = useState<any[] | undefined>(undefined); + const [purchases, setPurchases] = useState<TPurchase[] | undefined>(undefined); const { colorScheme } = useColorScheme(); const dark = colorScheme === "dark"; useEffect(() => { - setPurchases(myData); - }, []); - - type Purchase = { - purchase: any; - }; + setPurchases(props.route.params.purchases); + }, [props]); const handleReviewing = (purchaseId: string, seller: string) => { nav.navigate( @@ -46,7 +31,26 @@ export default function Purchase(props: any) { ); }; - const Card: React.FC<Purchase> = ({ purchase }) => { + const handleStatus = (status: string) => { + let s = ""; + status === "PREPARING_ORDER" + ? (s = "En preparacion") + : status === "OUT_FOR_DELIVERY" + ? (s = "Listo para delivery") + : status === "READY_FOR_PICKUP" + ? (s = "Listo para retirar") + : status === "DELIVERED" + ? (s = "Entregado") + : (s = "Indefinido"); + return s; + }; + + function formatted_date(d: Date) { + var result = ""; + result += d.getFullYear() + "/" + (d.getMonth() + 1) + "/" + d.getDate(); + return result; + } + const Card: React.FC<PurchaseCard> = ({ purchase }) => { return ( <View className=" @@ -58,17 +62,23 @@ export default function Purchase(props: any) { dark:bg-dark-mode-bg border-header-color rounded-md border-[1.13px]" > - <View className="flex-row-reverse inline-block align-middle"> - <Text className="text-[18px] p-[11px] dark:text-dark-mode-text font-semibold">Id: {purchase.id}</Text> - <Text className="text-[18px] p-[11px] mr-[157px] dark:text-dark-mode-text font-semibold"> - {Platform.OS === "android" ? purchase.date : "Fecha: " + purchase.date} + <View className="flex-row-reverse flex-1"> + <Text className="text-[18px] p-[11px] flex-wrap dark:text-dark-mode-text font-semibold"> + Status: {handleStatus(purchase.status)} + </Text> + <Text className="text-[18px] p-[12px] mr-4 dark:text-dark-mode-text font-semibold"> + {purchase.date + ? Platform.OS === "android" + ? purchase.date + : "Fecha: " + purchase.date + : "Fecha: " + formatted_date(new Date())} </Text> </View> <Divider style={dark ? { height: 1.5, backgroundColor: "white" } : { height: 1.5 }} /> <View className="flex-row justify-between"> - <Text className="text-[18px] p-[11px] dark:text-dark-mode-text font-semibold">{purchase.name}</Text> + <Text className="text-[18px] p-[11px] dark:text-dark-mode-text font-semibold">{purchase.sellerEmail}</Text> <Text className="text-[18px] p-[11px] mb-[-5px] dark:text-dark-mode-text font-semibold"> - USD {purchase.price} + USD {purchase.total} </Text> </View> @@ -81,16 +91,16 @@ export default function Purchase(props: any) { <CustomButton value={"Calificar"} style={{ width: "40%", margin: 35 }} - onPress={() => handleReviewing(purchase.id, purchase.seller)} + onPress={() => handleReviewing(purchase.id, purchase.sellerEmail)} isDisabled={false} /> <View className={Platform.select({ - ios: "absolute right-[40px] mt-[57px]", - android: "absolute right-[40px] mt-[55px]", + ios: "absolute right-[142px] mt-[58px]", + android: "absolute right-[136px] mt-[57px]", })} > - <Star size={24} color="white" /> + <Star size={21} color="white" /> </View> </View> </View> @@ -105,12 +115,16 @@ export default function Purchase(props: any) { className="w-full h-full bg-no-repeat" blurRadius={6} > - <FlatList - className="mt-2" - data={purchases} - keyExtractor={(item) => String(item.id)} - renderItem={({ item }) => <Card purchase={item} />} - /> + {purchases && purchases.length > 0 ? ( + <FlatList + className="mt-2" + data={purchases} + keyExtractor={(item) => String(item.id)} + renderItem={({ item }) => <Card purchase={item} />} + /> + ) : ( + <Text className="text-[18px] p-[11px] dark:text-dark-mode-text font-semibold">No has realizado compras</Text> + )} </ImageBackground> </> ); diff --git a/src/screens/customer/Review.tsx b/src/screens/customer/Review.tsx index f24ef7f..9301e64 100644 --- a/src/screens/customer/Review.tsx +++ b/src/screens/customer/Review.tsx @@ -1,73 +1,109 @@ -import { useFocusEffect, useNavigation } from "@react-navigation/core"; +import { useNavigation } from "@react-navigation/core"; import React, { useEffect, useState } from "react"; -import { FlatList, ImageBackground, Image, Text, View, TouchableOpacity } from "react-native"; +import { FlatList, ImageBackground, Text, View, TouchableOpacity, useWindowDimensions } from "react-native"; import { Divider } from "react-native-paper"; -import StarSvg from "../../components/Svgs/StarSvg"; import { useColorScheme } from "nativewind"; import { TUserReview } from "../../../urubuy"; import Loading from "../../components/Loading"; +import { StarRatingDisplay } from "react-native-star-rating-widget"; +import {} from "react-native"; +import { TabView, SceneMap, TabBar } from "react-native-tab-view"; -type Review = { - id: number; - name: string; - description: string; - date: string; - picture: string; - rating: number; - seller: Seller; +type ReviewUserCard = { + review: TUserReview; }; -type Seller = { - username: string; - email: string; - firstName: string; - lastName: string; - averageRating: number; - isBlocked: boolean; - addresses: string[]; -}; - -const seller3: Seller = { - username: "pepitoSeller", - email: "pepitoSeller", - firstName: "pepito", - lastName: "pepe", - averageRating: 4, - isBlocked: false, - addresses: [], -}; - -const myData = [ - { id: 1, date: "20/11/2011", name: "la cali 1", description: "muy buena", seller: seller3, rating: 4 }, - { id: 2, date: "10/11/2010", name: "la cali 2", description: "muy mala", seller: seller3, rating: 1 }, - { id: 3, date: "13/12/2013", name: "la cali 3", description: "muy muy", seller: seller3, rating: 3 }, - { id: 4, date: "14/12/2014", name: "4 la cali", description: "muy meh", seller: seller3, rating: 2 }, - { id: 5, date: "15/12/2015", name: "5 la cali", description: "muy pro", seller: seller3, rating: 5 }, -] as Review[]; - export default function Review(props: any) { const nav = useNavigation(); - const [reviews, setReviews] = useState<Review[] | undefined>(undefined); - const [reviewsUser, setReviewsUser] = useState<TUserReview[] | undefined>(undefined); + const [givenReviewsUser, setGivenReviewsUser] = useState<TUserReview[] | undefined>(undefined); + const [receivedUserReviews, setRecievedReviewsUser] = useState<TUserReview[] | undefined>(undefined); const { colorScheme } = useColorScheme(); const dark = colorScheme === "dark"; - useEffect(() => { - setReviewsUser(props.route.params.reviews); - }, [props]); + const layout = useWindowDimensions(); - useEffect(() => { - setReviews(myData); - }, []); + const [index, setIndex] = React.useState(0); + const [routes] = React.useState([ + { key: "receivedUserReview", title: "Reseñas de vendedores" }, + { key: "givenUserReview", title: "Reseñas a vendedores" }, + { key: "givenReviews", title: "Reseñas a productos" }, + ]); - type ReviewCard = { - review: Review; - }; + const _receivedUserReview = () => ( + <ImageBackground + source={require("../../../assets/abstract.jpg")} + resizeMode="cover" + className="w-full h-full bg-no-repeat" + blurRadius={6} + > + <View className="items-center justify-center h-max"> + {receivedUserReviews && receivedUserReviews.length > 0 ? ( + <> + <FlatList + ListHeaderComponent={ + <Text className="text-[35px] p-[11px] text-dark-mode-text font-semibold"> + Calificaciones recibidas por vendedores + </Text> + } + className="mt-2" + data={receivedUserReviews} + keyExtractor={(item) => String(item.id)} + renderItem={({ item }) => <Card review={item} />} + /> + </> + ) : null} + </View> + </ImageBackground> + ); - type ReviewUserCard = { - review: TUserReview; - }; + const _givenUserReview = () => ( + <ImageBackground + source={require("../../../assets/abstract.jpg")} + resizeMode="cover" + className="w-full h-full bg-no-repeat" + blurRadius={6} + > + <View className="items-center justify-center h-max"> + {givenReviewsUser ? ( + givenReviewsUser.length > 0 ? ( + <FlatList + className="mt-2" + ListHeaderComponent={ + <Text className="text-[35px] p-[11px] text-dark-mode-text font-semibold"> + Calificaciones dadas a vendedores + </Text> + } + data={givenReviewsUser} + keyExtractor={(item) => String(item.id)} + renderItem={({ item }) => <Card review={item} />} + /> + ) : ( + <Text className="text-[18px] p-[11px] text-[#fff] font-semibold"> + No ha calificado a ningun usuario y/o producto + </Text> + ) + ) : null} + </View> + </ImageBackground> + ); + + const _givenReviews = (jumpTo: any) => ( + <View style={{ flex: 1 }}> + <Text>Third Route</Text> + </View> + ); + + const renderScene = SceneMap({ + receivedUserReview: _receivedUserReview, + givenUserReview: _givenUserReview, + givenReviews: _givenReviews, + }); + + useEffect(() => { + setGivenReviewsUser(props.route.params.givenReviews); + setRecievedReviewsUser(props.route.params.receivedUserReviews); + }, [props]); const handleProfileSeller = (seller: string) => { nav.navigate( @@ -84,8 +120,7 @@ export default function Review(props: any) { className=" ml-[2%] mb-[10px] - w-[96%] - min-h-auto + w-[96%] bg-[#ffffff] dark:bg-dark-mode-bg border-header-color rounded-[5px] border-[1.33px]" @@ -95,28 +130,19 @@ export default function Review(props: any) { Fecha: {Date.now()} </Text> <View className="flex-row p-2"> - {[...Array(review.rating)].map((x, i) => ( - <View key={i}> - <StarSvg color={dark ? "#f1c533" : "#0c35c5"} /> - </View> - ))} + <StarRatingDisplay + rating={review.rating ? review?.rating : 1} + starStyle={{ marginHorizontal: -2 }} + color={dark ? "#cf8c40" : "blue"} + /> </View> </View> <Divider style={dark ? { height: 1.5, backgroundColor: "white" } : { height: 1.5 }} /> <View className="flex-row justify-between"> - <Text className="text-[18px] p-[5px] ml-6 mt-3 dark:text-dark-mode-text font-semibold"> - {review.description} - </Text> - - <Text className="text-[18px] p-[5px] mr-6 mt-3 dark:text-dark-mode-text font-semibold"> + <Text className="text-[18px] flex-wrap p-[5px] ml-6 mt-3 dark:text-dark-mode-text font-semibold"> {review.description} </Text> </View> - <Image - source={require("../../../assets/bgColorful.jpg")} - className="max-h-[90%] max-w-[39%] h-[155px] ml-2 mt-[-10px]" - resizeMode="contain" - /> <View className="flex-row"> <Text className="text-[18px] p-[11px] dark:text-dark-mode-text font-semibold">Vendedor</Text> <TouchableOpacity onPress={() => handleProfileSeller(review.sellerEmail)}> @@ -130,30 +156,82 @@ export default function Review(props: any) { }; return ( - <> - <ImageBackground - source={require("../../../assets/abstract.jpg")} - resizeMode="cover" - className="w-full h-full bg-no-repeat" - blurRadius={6} - > - {reviewsUser ? ( - reviewsUser.length > 0 ? ( - <FlatList - className="mt-2" - data={reviewsUser} - keyExtractor={(item) => String(item.id)} - renderItem={({ item }) => <Card review={item} />} - /> + <ImageBackground + source={require("../../../assets/abstract.jpg")} + resizeMode="cover" + className="w-full h-full bg-no-repeat" + blurRadius={6} + > + <TabView + navigationState={{ index, routes }} + renderScene={renderScene} + onIndexChange={setIndex} + swipeEnabled={true} + animationEnabled={true} + pagerStyle={{ backgroundColor: "white" }} + initialLayout={{ width: layout.width, height: layout.height }} + style={{ backgroundColor: "#fff" }} + renderTabBar={(props) => ( + <TabBar + {...props} + activeColor="#0c35c5" + indicatorStyle={{ backgroundColor: "#0c35c5" }} + labelStyle={{ fontSize: 16, fontWeight: "bold" }} + style={{ backgroundColor: "white" }} + /> + )} + /> + </ImageBackground> + ); + /*<> + + <View className="items-center justify-center my-auto"> + {receivedUserReviews && receivedUserReviews.length > 0 ? ( + <> + <FlatList + ListHeaderComponent={ + <Text className="text-[35px] p-[11px] text-dark-mode-text font-semibold"> + Calificaciones recibidas por vendedores + </Text> + } + className="mt-2" + data={receivedUserReviews} + keyExtractor={(item) => String(item.id)} + ListFooterComponent={ + givenReviewsUser ? ( + givenReviewsUser.length > 0 ? ( + <FlatList + className="mt-2" + ListHeaderComponent={ + <Text className="text-[35px] p-[11px] text-dark-mode-text font-semibold"> + Calificaciones dadas a vendedores + </Text> + } + data={givenReviewsUser} + keyExtractor={(item) => String(item.id)} + renderItem={({ item }) => <Card review={item} />} + /> + ) : ( + <Text className="text-[18px] p-[11px] text-[#fff] font-semibold"> + No ha calificado a ningun usuario y/o producto + </Text> + ) + ) : ( + <Text className="text-[18px] p-[11px] text-[#fff] font-semibold"> + Todavia no ha recibido calificaciones + </Text> + ) + } + renderItem={({ item }) => <Card review={item} />} + /> + </> ) : ( - <Text className="text-[18px] p-[11px] text-header-color dark:text-[#f1c533] font-semibold"> - No hay reviews + <Text className="text-[18px] p-[11px] text-[#fff] font-semibold"> + Todavia no ha recibido calificaciones </Text> - ) - ) : ( - <Loading text="Cargando..." bg={true} /> - )} + )} + </View> </ImageBackground> </> - ); + );*/ } diff --git a/src/screens/customer/Settings.tsx b/src/screens/customer/Settings.tsx index d43afea..7dfa4d6 100644 --- a/src/screens/customer/Settings.tsx +++ b/src/screens/customer/Settings.tsx @@ -163,7 +163,7 @@ function Settings() { {!loading ? ( <> - <Text className="mt-8 mr-7 p-2 text-[50px] font-extrabold text-[#fff]">Configuración</Text> + <Text className="mt-8 mr-7 p-2 text-[45px] font-extrabold text-[#fff]">Configuración</Text> <Divider style={{ height: 1.3, backgroundColor: "white" }} /> <ScrollView showsVerticalScrollIndicator={false}> <Text className="text-[#fff] text-[18px] font-bold mt-[20px] ml-3 p-2">Opciones generales </Text> diff --git a/src/screens/customer/ShoppingCart.tsx b/src/screens/customer/ShoppingCart.tsx index e3c2f39..2d239a8 100644 --- a/src/screens/customer/ShoppingCart.tsx +++ b/src/screens/customer/ShoppingCart.tsx @@ -93,7 +93,7 @@ export default function ShoppingCart() { getCart(); getAddresses(); setNewCustomerAddress(""); - setLoading(false); + setLoading(true); }); return unsubscribe; }, [shoppingCart, shoppingPost]); @@ -137,7 +137,8 @@ export default function ShoppingCart() { .catch((err) => console.log(err.response.data)); }); }) - .catch((err) => console.log(err.response.data)); + .catch((err) => console.log(err.response.data)) + .finally(() => setLoading(false)); }; const getAddresses = async () => { @@ -607,7 +608,9 @@ export default function ShoppingCart() { blurRadius={6} > {loading ? ( - <Loading text="Cargando" bg={true} /> + <View className="mx-auto my-auto"> + <Loading text="Cargando..." bg={true} /> + </View> ) : ( <FlatList ListHeaderComponent={ diff --git a/src/services/Requests.tsx b/src/services/Requests.tsx index 0168787..8aec79b 100644 --- a/src/services/Requests.tsx +++ b/src/services/Requests.tsx @@ -4,7 +4,7 @@ import Constants from "expo-constants"; import { TCustomer, TCheckout, TUserKC, TReview, TUserReview } from "../../urubuy"; const iLocal = axios.create({ - baseURL: Constants.manifest?.extra?.URL_LOCAL, // ultra relativo cada pc tiene la suya localhost no funca :/ + baseURL: Constants.manifest?.extra?.URL_CLOUD, // ultra relativo cada pc tiene la suya localhost no funca :/ headers: { "Content-Type": "application/json" }, }); @@ -322,7 +322,7 @@ export const suspendAccount = async (email: string) => { }; export const reviewSeller = async (review: TUserReview) => { - //console.log(review); + console.log(review); return iLocal.post("userReview/add", review); }; diff --git a/tailwind.config.js b/tailwind.config.js index 63f7dbc..73136e6 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -9,6 +9,7 @@ module.exports = { "custom-red": "#9e3c3c", "dark-mode-bg": "#292626", "dark-mode-text": "#fff", + "gold-buy": "#cf8c40", }, }, plugins: [], diff --git a/urubuy.d.ts b/urubuy.d.ts index c0984e8..8d334b9 100644 --- a/urubuy.d.ts +++ b/urubuy.d.ts @@ -60,6 +60,7 @@ export type TCustomer = { averageRating: number; givenUserReviews?: TUserReview[]; receivedUserReviews?: TUserReview[]; + purchases: TPurchase[]; }; export type TSeller = { @@ -73,6 +74,8 @@ export type TSeller = { barcode: string; personalId: string; averageRating: number; + givenUserReviews?: TUserReview[]; + receivedUserReviews?: TUserReview[]; }; export type TShoppingCart = { @@ -116,6 +119,18 @@ export type TCheckoutShoppingPost = { address: string; }; +export type TPurchase = { + id: string; + status: string; + date: string; + total: number; + address: string; + isDelivery: boolean; + orderPayPalId: string; + sellerEmail: string; + customerEmail: string; +}; + export type TUserReview = { id: string; rating: number; -- GitLab From e5b278ad51f1c61d3223fdaf79691d8f2bd0560d Mon Sep 17 00:00:00 2001 From: "mathias.fernandez.bo" <mathias.fernandez.bo@fing.edu.uy> Date: Wed, 7 Dec 2022 05:57:24 -0300 Subject: [PATCH 3/6] ready to deploy apk --- app.json | 21 ++- assets/favicon.png | Bin 7890 -> 0 bytes eas.json | 18 +++ src/components/FAQ.tsx | 59 +++++++ src/components/Navigation/SideMenu.tsx | 85 ++++++++-- src/components/SettingNotifications.tsx | 23 ++- src/screens/{customer => }/Help.tsx | 20 ++- src/screens/Notification.tsx | 91 ++++++++--- src/screens/ProductReviews.tsx | 137 ++++++++++++++++ src/screens/SellerReviews.tsx | 134 ++++++++++++++++ src/screens/ShoppingPost.tsx | 52 +++++-- src/screens/UserProfile.tsx | 70 +++++++-- src/screens/customer/Checkout.tsx | 2 +- src/screens/customer/GiveReview.tsx | 136 ++++++++++------ src/screens/customer/Profile.tsx | 35 +++-- src/screens/customer/Purchase.tsx | 138 +++++++++------- src/screens/customer/Review.tsx | 199 ++++++++++++++---------- src/screens/customer/Settings.tsx | 49 ++++-- src/services/Requests.tsx | 17 +- urubuy.d.ts | 14 +- 20 files changed, 1011 insertions(+), 289 deletions(-) delete mode 100644 assets/favicon.png create mode 100644 eas.json create mode 100644 src/components/FAQ.tsx rename src/screens/{customer => }/Help.tsx (83%) create mode 100644 src/screens/ProductReviews.tsx create mode 100644 src/screens/SellerReviews.tsx diff --git a/app.json b/app.json index 62dca2d..a0fb3ea 100644 --- a/app.json +++ b/app.json @@ -12,10 +12,13 @@ "URL_CLOUD": "http://backend.uru-buy.me/", "URL_KC": "http://urubuy.ddns.net:8080/realms/Urubuy/protocol/openid-connect", "URL_KC_ADMIN": "http://urubuy.ddns.net:8080/admin/realms/Urubuy", - "DEVICE_ID": "RNExpo" + "DEVICE_ID": "RNExpo", + "eas": { + "projectId": "f25ad283-9f97-4f12-a6ae-fd95a159f82f" + } }, "orientation": "portrait", - "icon": "./assets/icon.png", + "icon": "./assets/placeholder.png", "userInterfaceStyle": "automatic", "splash": { "image": "./assets/splash.png", @@ -25,19 +28,25 @@ "updates": { "fallbackToCacheTimeout": 0 }, - "assetBundlePatterns": ["**/*"], + "assetBundlePatterns": [ + "**/*" + ], "ios": { "supportsTablet": true, - "bundleIdentifier": "com.fing.frontend.urubuy", + "bundleIdentifier": "com.fing.frontmobile", "buildNumber": "1.0.0" }, "android": { "adaptiveIcon": { "foregroundImage": "./assets/adaptive-icon.png", - "backgroundColor": "#FFFFFF", + "backgroundColor": "#0c35c5", "package": "com.fing.frontend.urubuy", "versionCode": "1.0.0" - } + }, + "permissions": [ + "android.permission.RECORD_AUDIO" + ], + "package": "com.fing.frontmobile" }, "web": { "favicon": "./assets/favicon.png" diff --git a/assets/favicon.png b/assets/favicon.png deleted file mode 100644 index 6e747acab7476b6068fb6248736582c4675b83c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7890 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 diff --git a/eas.json b/eas.json new file mode 100644 index 0000000..7a6f4b0 --- /dev/null +++ b/eas.json @@ -0,0 +1,18 @@ +{ + "cli": { + "version": ">= 2.9.0" + }, + "build": { + "development": { + "developmentClient": true, + "distribution": "internal" + }, + "preview": { + "distribution": "internal" + }, + "production": {} + }, + "submit": { + "production": {} + } +} diff --git a/src/components/FAQ.tsx b/src/components/FAQ.tsx new file mode 100644 index 0000000..532f19d --- /dev/null +++ b/src/components/FAQ.tsx @@ -0,0 +1,59 @@ +import { useColorScheme } from "nativewind"; +import { Copyright } from "phosphor-react-native"; +import React from "react"; +import { ScrollView, Text, View } from "react-native"; + +export default function FAQ() { + const { colorScheme } = useColorScheme(); + let dark = colorScheme === "dark"; + return ( + <> + <View className="h-full w-full bg-[#fff] dark:bg-dark-mode-bg"> + <ScrollView showsVerticalScrollIndicator={false}> + <View className="flex flex-col items-center justify-center"> + <Text className="text-[#000] dark:text-[#fff] text-[20px] font-bold mt-5 underline"> FAQ </Text> + <View className="flex flex-col items-center justify-center"> + <Text className="text-[#000] dark:text-[#fff] text-[22px] font-bold mt-5">¿Qué es la aplicación?</Text> + <Text className="text-[#000] dark:text-[#fff] text-[17px] font-bold p-2"> + UruBuy es una plataforma de compra y venta de productos o popularmente conocida como una app de + e-commerce. Desde esta la aplicación podrás comprar productos de manera segura y confiable, teniendo la + seguridad que brinda UruBuy, que verifica la identidad de cada vendedor a traves del sistema de + identificación confirmada, que utiliza los datos reales de la cedula de identidad uruguaya, y utilizando + el método de pago más seguro y confiable de hoy en dia, PayPal. + </Text> + <Text className="text-[#000] dark:text-[#fff] text-[22px] font-bold mt-5">¿Cómo comprar?</Text> + <Text className="text-[#000] dark:text-[#fff] text-[17px] font-bold p-2"> + En primera instancia, deberas registrarte en la plataforma, a través del formulario de registro de esta + aplicación, o desde la pagina principal http://uru-buy.me/ {"\n"} + Una vez registrado, deberás validar tu email para iniciar sesión en UruBuy. Si te gustó un producto, lo + puedes agregar al carrito desde la página del producto. Ten en cuenta que podrás agregar varios + productos al carrito, y elegir la dirección de retiro, o de delivery en caso de que el vendedor acepte + el mismo. Una vez que tengas todos los productos que deseas comprar en el carrito, deberás proceder a la + realizar el checkout, donde se te listará el detalle de tus productos con sus descuentos y costo de + delivery aplicados en caso que corresponda, y el total a pagar. Paypal ofrece los métodos de pagos + tradicionales de Visa y Mastercard para tarjetas de crédito o débito, como de otras tarjetas del + exterior, además de su ya conocida transferencia paypal entre cuentas. Si tu pago se procesa + correcamente, un email con la factura de compra será enviada, y el vendedor recibirá tu orden para + preparar. Nosotros te avisaremos cuando tu compra cambie de estado! + </Text> + <Text className="text-[#000] dark:text-[#fff] text-[22px] font-bold mt-5">¿Cómo calificar?</Text> + <Text className="text-[#000] dark:text-[#fff] text-[17px] font-bold p-2"> + Las calificaciones están habilitadas a aquellos usuarios que completen una compra, y que hayan recibido + el producto en sus manos. Para realizar una reseña de un vendedor, en la página de tu perfil puedes + acceder a tus compras, y allà se te listaran las mismas. Elige la que desees calificar y tendrás la + posibilidad de calificar al vendedor y a los productos de esa compra. Ten en cuenta que solamente podrás + calificar una vez por compra, y que las calificaciones son visibles para todos los usuarios de la + plataforma. Tambien, puedes subir fotos a la reseña de productos. + </Text> + <Text className="text-[#000] dark:text-[#fff] text-[22px] font-bold mt-5">¿Tienes alguna duda?</Text> + <Text className="text-[#000] dark:text-[#fff] text-[17px] font-bold p-2"> + No dudes en comunicarte con nosotros a través de nuestro email urubuying@gmail, estaremos encantados de + ayudarte + </Text> + </View> + </View> + </ScrollView> + </View> + </> + ); +} diff --git a/src/components/Navigation/SideMenu.tsx b/src/components/Navigation/SideMenu.tsx index de2af60..bfedccf 100644 --- a/src/components/Navigation/SideMenu.tsx +++ b/src/components/Navigation/SideMenu.tsx @@ -7,7 +7,7 @@ import Home from "../../screens/Home"; import Login from "../../screens/Login"; import SignUp from "../../screens/SignUp"; import LogoutScreen from "../../screens/customer/Logout"; -import Help from "../../screens/customer/Help"; +import Help from "../../screens/Help"; import Profile from "../../screens/customer/Profile"; import { createDrawerNavigator } from "@react-navigation/drawer"; import { getData, getUserCart, removeData } from "../../services/Requests"; @@ -19,9 +19,12 @@ import UserProfile from "../../screens/UserProfile"; import { useColorScheme } from "nativewind"; import PrivacyPolicy from "../PrivacyPolicy"; import Likes from "../../screens/customer/Likes"; -import ReviewSeller from "../../screens/customer/GiveReview"; +import GiveReview from "../../screens/customer/GiveReview"; import CheckoutScreen from "../../screens/customer/Checkout"; import Addresses from "../../screens/customer/Addresses"; +import SellerReview from "../../screens/SellerReviews"; +import ProductReviews from "../../screens/ProductReviews"; +import FAQ from "../FAQ"; const Drawer = createDrawerNavigator(); @@ -82,6 +85,7 @@ export default function SideMenu() { return ( <Drawer.Navigator + backBehavior="history" screenOptions={{ drawerStyle: dark ? { backgroundColor: "#292626" } : { backgroundColor: "white" }, }} @@ -104,11 +108,6 @@ export default function SideMenu() { /*header carrito */ headerRight: (focus) => ( <View className="flex-row items-center justify-center"> - {/*user ? ( - {<TouchableOpacity onPress={() => handleLikes(navigation, username)}> - <Heart size={24} style={{ marginEnd: 15 }} color={focus ? "#fff" : "grey"} /> - </TouchableOpacity> - ) : null}*/} {user ? ( <TouchableOpacity onPress={() => handlePressCart(navigation, cartCounter)}> <ShoppingCart size={24} style={{ marginEnd: 15 }} color={focus ? "#fff" : "grey"} /> @@ -217,7 +216,7 @@ export default function SideMenu() { <Drawer.Screen name="Notification" options={{ - headerTitle: "Nuevos productos!!", + headerTitle: "", headerTintColor: "#fff", headerStyle: { backgroundColor: "#0c35c5", @@ -267,6 +266,46 @@ export default function SideMenu() { {(props) => <Review {...props} />} </Drawer.Screen> + <Drawer.Screen + name="SellerReviews" + options={({ navigation }) => ({ + headerTitle: "Calificaciones", + headerTintColor: "#fff", + headerTitleAlign: "center", + headerStyle: { + backgroundColor: "#0c35c5", + }, + drawerItemStyle: { display: "none" }, + headerLeft: (focus) => ( + <TouchableOpacity onPress={() => navigation.goBack()}> + <ArrowLeft size={24} style={{ padding: 10, marginLeft: 10 }} color={focus ? "#fff" : "grey"} /> + </TouchableOpacity> + ), + })} + > + {(props) => <SellerReview {...props} />} + </Drawer.Screen> + + <Drawer.Screen + name="ProductReviews" + options={({ navigation }) => ({ + headerTitle: "Calificaciones", + headerTintColor: "#fff", + headerTitleAlign: "center", + headerStyle: { + backgroundColor: "#0c35c5", + }, + drawerItemStyle: { display: "none" }, + headerLeft: (focus) => ( + <TouchableOpacity onPress={() => navigation.goBack()}> + <ArrowLeft size={24} style={{ padding: 10, marginLeft: 10 }} color={focus ? "#fff" : "grey"} /> + </TouchableOpacity> + ), + })} + > + {(props) => <ProductReviews {...props} />} + </Drawer.Screen> + <Drawer.Screen name="ShoppingPost" options={({ navigation }) => ({ @@ -297,7 +336,7 @@ export default function SideMenu() { }, drawerItemStyle: { display: "none" }, headerLeft: (focus) => ( - <TouchableOpacity onPress={() => navigation.goBack(null)}> + <TouchableOpacity onPress={() => navigation.goBack()}> <ArrowLeft size={24} style={{ padding: 10, marginLeft: 10 }} color={focus ? "#fff" : "grey"} /> </TouchableOpacity> ), @@ -317,7 +356,7 @@ export default function SideMenu() { }, drawerItemStyle: { display: "none" }, headerLeft: (focus) => ( - <TouchableOpacity onPress={() => navigation.navigate("Help") as never}> + <TouchableOpacity onPress={() => navigation.goBack() as never}> <ArrowLeft size={24} style={{ padding: 10, marginLeft: 10 }} color={focus ? "#fff" : "grey"} /> </TouchableOpacity> ), @@ -327,7 +366,27 @@ export default function SideMenu() { </Drawer.Screen> <Drawer.Screen - name="ReviewSeller" + name="FAQ" + options={({ navigation }) => ({ + headerTitle: "FAQ", + headerTintColor: "#fff", + headerTitleAlign: "center", + headerStyle: { + backgroundColor: "#0c35c5", + }, + drawerItemStyle: { display: "none" }, + headerLeft: (focus) => ( + <TouchableOpacity onPress={() => navigation.goBack() as never}> + <ArrowLeft size={24} style={{ padding: 10, marginLeft: 10 }} color={focus ? "#fff" : "grey"} /> + </TouchableOpacity> + ), + })} + > + {() => <FAQ />} + </Drawer.Screen> + + <Drawer.Screen + name="GiveReview" options={({ navigation }) => ({ headerTitle: "Calificar compra", headerTintColor: "#fff", @@ -336,14 +395,14 @@ export default function SideMenu() { backgroundColor: "#0c35c5", }, headerLeft: (focus) => ( - <TouchableOpacity onPress={() => navigation.navigate("Perfil") as never}> + <TouchableOpacity onPress={() => navigation.goBack() as never}> <ArrowLeft size={24} style={{ padding: 10, marginLeft: 10 }} color={focus ? "#fff" : "grey"} /> </TouchableOpacity> ), drawerItemStyle: { display: "none" }, })} > - {(props) => <ReviewSeller {...props} />} + {(props) => <GiveReview {...props} />} </Drawer.Screen> <Drawer.Screen diff --git a/src/components/SettingNotifications.tsx b/src/components/SettingNotifications.tsx index c5eaa31..4d4d445 100644 --- a/src/components/SettingNotifications.tsx +++ b/src/components/SettingNotifications.tsx @@ -21,6 +21,7 @@ export default function SettingNotifications() { title: "", body: "", category: "", + purchaseId: "", }); const notificationListener = useRef(); const responseListener = useRef(); @@ -52,6 +53,7 @@ export default function SettingNotifications() { title: notification.request.content.title, body: notification.request.content.body, category: notification.request.content.data.category, + purchaseId: notification.request.content.data.purchaseId, }); }) as never; @@ -59,12 +61,21 @@ export default function SettingNotifications() { responseListener.current = Notifications.addNotificationResponseReceivedListener(() => { // if (notificationData.category === 'promociones') { // filter by category of notifications let k = notificationData.category; - nav.navigate( - "Notification" as never, - { - category: `${k}`, - } as never, - ); + console.log("k es: ", k); + k === "estado" + ? nav.navigate( + "Notification" as never, + { + category: k, + purchaseId: notificationData.purchaseId, + } as never, + ) + : nav.navigate( + "Notification" as never, + { + category: `${k}`, + } as never, + ); }) as never; }, [notificationData, nav]); diff --git a/src/screens/customer/Help.tsx b/src/screens/Help.tsx similarity index 83% rename from src/screens/customer/Help.tsx rename to src/screens/Help.tsx index 13982dd..f281c1b 100644 --- a/src/screens/customer/Help.tsx +++ b/src/screens/Help.tsx @@ -16,6 +16,10 @@ function Help() { nav.navigate("PrivacyPolicy" as never); }; + const handleFAQ = () => { + nav.navigate("FAQ" as never); + }; + return ( <View className="w-full h-full bg-white dark:bg-dark-mode-bg"> <Text className="mt-8 mr-7 p-2 text-[45px] font-extrabold text-[#000] dark:text-dark-mode-text">Ayuda</Text> @@ -28,12 +32,10 @@ function Help() { <Question weight="fill" size={19} color={dark ? "white" : "black"} /> <Text className="text-[#000] dark:text-[#fff] text-[17px] font-bold mx-auto my-auto">¿Quienes somos?</Text> </TouchableOpacity> - <TouchableOpacity className="p-2 mt-2 h-10 flex-row bg-[#fff] dark:bg-[#292626] border-[#32377B] dark:border-[#ffff] border-[1.33px] rounded-2xl"> - <Question weight="fill" size={19} color={dark ? "white" : "black"} /> - <Text className="text-[#000] dark:text-[#fff] text-[17px] font-bold mx-auto my-auto">¿Cómo comprar?</Text> - <CaretRight weight="bold" size={19} color={dark ? "white" : "black"} /> - </TouchableOpacity> - <TouchableOpacity className="p-2 mt-2 h-10 flex-row bg-[#fff] dark:bg-[#292626] border-[#32377B] dark:border-[#ffff] border-[1.33px] rounded-2xl"> + <TouchableOpacity + onPress={() => handleFAQ()} + className="p-2 mt-2 h-10 flex-row bg-[#fff] dark:bg-[#292626] border-[#32377B] dark:border-[#ffff] border-[1.33px] rounded-2xl" + > <Question weight="fill" size={19} color={dark ? "white" : "black"} /> <Text className="text-[#000] dark:text-[#fff] text-[17px] font-bold mx-auto my-auto"> Preguntas frecuentes @@ -79,7 +81,11 @@ function Help() { <TouchableOpacity className="absolute right-[-15px] w-16 h-16 top-3" onPress={() => setWHOAMI(!WHOAMI)}> <XCircle size={25} weight="regular" color={colorScheme === "dark" ? "white" : "black"} /> </TouchableOpacity> - <Text className="p-2 mt-3 dark:text-dark-mode-text"> WE ARE THE CHAMPIONS ! maifrend </Text> + <Text className="font-bold text-header-color dark:text-gold-buy">UruBuy @ 2022</Text> + <Text className="p-2 mt-3 font-medium dark:text-dark-mode-text"> + Somos un grupo de desarrolladores de Uruguay, estudiantes de Tecnólogo en informática. Esta aplicación + fue desarrollada como proyecto final de la carrera. + </Text> </View> </View> </Modal> diff --git a/src/screens/Notification.tsx b/src/screens/Notification.tsx index 95addbe..ee66528 100644 --- a/src/screens/Notification.tsx +++ b/src/screens/Notification.tsx @@ -1,35 +1,55 @@ import React, { useEffect, useState } from "react"; import { FlatList, ImageBackground, Text, TouchableOpacity, View } from "react-native"; import { Card } from "@rneui/themed"; -import { TShoppingPost } from "../../urubuy"; -import { getShoppingPosts } from "../services/Requests"; +import { TPurchase, TShoppingPost } from "../../urubuy"; +import { getPurchaseById, getShoppingPosts } from "../services/Requests"; import { useColorScheme } from "nativewind"; import { useNavigation } from "@react-navigation/core"; import Loading from "../components/Loading"; import { Truck } from "phosphor-react-native"; +import { handleStatus } from "./customer/Purchase"; const noitem = require("../../assets/noitem.png"); +type ScrollList = { + data: TShoppingPost; +}; + export default function Notification(props: any) { let [shoppingPost, setShoppingPost] = useState<TShoppingPost[] | undefined>(undefined); const nav = useNavigation(); const { colorScheme } = useColorScheme(); let dark = colorScheme === "dark"; const [loading, setLoading] = useState(false); + const [status, setStatus] = useState(false); + const [purchase, setPurchase] = useState<TPurchase | undefined>(undefined); + const [categoryNotification, setCategoryNotification] = useState<string>(""); useEffect(() => { let cat = props.route.params.category; + setCategoryNotification(cat); if (cat === "promociones") { fetchPromotions(); } else if (cat === "nuevos") { fetchNews(); - } - + } else if (cat === "estado") { + statusChanged(props.route.params.purchaseId); + } else errorNotification(); const unsubscribe = nav.addListener("focus", () => { setLoading(true); }); return unsubscribe; }, [nav, props]); + useEffect(() => { + const unsubscribe = nav.addListener("blur", () => { + setShoppingPost(undefined); + setPurchase(undefined); + setStatus(false); + setCategoryNotification(""); + }); + return unsubscribe; + }, [nav]); + async function fetchPromotions() { getShoppingPosts() .then((res: any) => { @@ -47,32 +67,42 @@ export default function Notification(props: any) { }); } + async function statusChanged(id: number) { + setStatus(true); + getPurchaseById(id) + .then((res) => { + setPurchase(res?.data); + }) + .catch((e) => console.log(e)) + .finally(() => { + setLoading(false); + }); + } + async function fetchNews() { + if (purchase) setPurchase(undefined); getShoppingPosts() .then((res: any) => { if (res.status === 200) { let posts: TShoppingPost[] = res.data; let zerok: TShoppingPost[] = posts.filter((item: TShoppingPost) => item.isNew === true); setShoppingPost(zerok); + setLoading(false); } }) .catch((err: any) => { console.log(err.response.data); }) - .finally(() => { - setLoading(false); - }); + .finally(() => {}); } - useEffect(() => { - const unsubscribe = nav.addListener("blur", () => { - setShoppingPost(undefined); - }); - return unsubscribe; - }, [nav]); - - type ScrollList = { - data: TShoppingPost; + const errorNotification = () => { + setLoading(false); + return ( + <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}> + <Text style={{ fontSize: 20, color: dark ? "white" : "black" }}>Ha ocurrido un error, lo sentimos.</Text> + </View> + ); }; const handlePress = (data: any) => { @@ -144,6 +174,18 @@ export default function Notification(props: any) { const _renderItem = ({ item }: { item: TShoppingPost }) => <ListItem data={item} />; + const _header = () => { + return categoryNotification === "promociones" ? ( + <View className="mt-3"> + <Text className="text-2xl font-bold text-center dark:text-dark-mode-text">Rebajas!</Text> + </View> + ) : categoryNotification === "nuevos" ? ( + <View className="mt-3"> + <Text className="text-2xl font-bold text-center dark:text-dark-mode-text">Productos nuevos</Text> + </View> + ) : null; + }; + return ( <View className="items-center justify-center flex-1"> <ImageBackground @@ -152,15 +194,28 @@ export default function Notification(props: any) { className="w-full h-full bg-no-repeat" blurRadius={6} > - {!loading ? ( + {status && purchase && categoryNotification === "estado" ? ( + <View className="w-auto mx-auto my-auto border-[1.33px] border-header-color rounded-3xl h-auto"> + <Text className="text-[22px] p-4 font-bold dark:text-dark-mode-text"> + Estado de la compra: {purchase.orderPayPalId} + </Text> + <Text className="text-[17px] p-3 font-bold dark:text-dark-mode-text"> + Estado: {handleStatus(purchase?.status)} + </Text> + <Text className="text-[17px] p-3 font-bold dark:text-dark-mode-text">Fecha: {purchase?.date}</Text> + </View> + ) : !loading ? ( <FlatList data={shoppingPost} + ListHeaderComponent={_header} keyExtractor={(item) => item.id.toString()} renderItem={_renderItem} showsVerticalScrollIndicator={false} /> ) : ( - <Loading text="Cargando ofertas" bg={true} /> + <View className="my-auto"> + <Loading text="Cargando ofertas" bg={true} /> + </View> )} </ImageBackground> </View> diff --git a/src/screens/ProductReviews.tsx b/src/screens/ProductReviews.tsx new file mode 100644 index 0000000..0a68c7d --- /dev/null +++ b/src/screens/ProductReviews.tsx @@ -0,0 +1,137 @@ +import { useFocusEffect, useNavigation } from "@react-navigation/core"; +import React, { useEffect, useState } from "react"; +import { FlatList, ImageBackground, Text, View, TouchableOpacity, useWindowDimensions } from "react-native"; +import { Divider } from "react-native-paper"; +import { useColorScheme } from "nativewind"; +import { TReview } from "../../urubuy"; +import { StarRatingDisplay } from "react-native-star-rating-widget"; +import { getCustomerProfile } from "../services/Requests"; +import SliderSlick from "../components/SliderSlick"; + +type ReviewCard = { + review: TReview; +}; + +type TReviewUsername = { + username: string; + reviewId: number; +}; + +export default function ProductReview(props: any) { + const [receivedReviews, setRecievedReviews] = useState<TReview[] | undefined>([]); + const [reviewUsername, setReviewUsername] = useState<TReviewUsername[] | undefined>([]); + const { colorScheme } = useColorScheme(); + const dark = colorScheme === "dark"; + const nav = useNavigation(); + + useFocusEffect(() => { + setRecievedReviews(props.route.params.reviews); + // handleCustomer(props.route.params.reviews); + }); + + useEffect(() => { + const unsuscribe = nav.addListener("blur", () => { + setRecievedReviews([]); + setReviewUsername([]); + }); + return unsuscribe; + }, []); + + // not working customer username by review idk why repite el mismo nombre + /* const handleCustomer = (reviews: TReview[]) => { + let k: TReviewUsername[] = []; + if (reviews && reviews.length > 0) { + reviews.forEach((r) => { + getCustomerProfile(r.customerEmail).then((res) => { + if (res.status === 200) { + if (reviewUsername?.find((y) => y.reviewId === +r.id) === undefined) + setReviewUsername((p) => [...p!, { username: res.data.username, reviewId: +r.id }]); + } + }); + }); + } + };*/ + + const handleProductClicked = (productId: string) => { + nav.navigate( + "ShoppingPost" as never, + { + id: productId, + } as never, + ); + }; + + const ReviewCard: React.FC<ReviewCard> = ({ review }) => { + return ( + <View + className=" + ml-[2%] + mb-[10px] + w-[96%] + bg-[#fff] + dark:bg-dark-mode-bg + border-header-color rounded-[5px] border-[1.33px]" + > + <View className="flex-row justify-between"> + <Text className="text-[18px] p-[11px] items-start dark:text-dark-mode-text font-semibold"> + Fecha: {review.date} + </Text> + <View className="flex-row p-2"> + <StarRatingDisplay + rating={review.rating ? review?.rating : 1} + starStyle={{ marginHorizontal: -2 }} + color={dark ? "#cf8c40" : "blue"} + /> + </View> + </View> + <Divider style={dark ? { height: 1.5, backgroundColor: "white" } : { height: 1.5 }} /> + <TouchableOpacity onPress={() => handleProductClicked(review.shoppingPost.id)}> + <Text className="text-[18px] p-[11px] dark:text-dark-mode-text font-semibold"> + {review.shoppingPost.title} + </Text> + </TouchableOpacity> + <View className="flex-row justify-between"> + <Text className="text-[18px] flex-wrap p-[5px] ml-6 mt-3 dark:text-dark-mode-text font-semibold"> + {review.description} + </Text> + </View> + <View className="p-2 scale-50 -mb-28 -mt-28"> + <SliderSlick pictures={review.base64Images} /> + </View> + </View> + ); + }; + + const _separator = () => { + return <Divider style={{ padding: 1.13, backgroundColor: "white", margin: 15 }} />; + }; + + return ( + <ImageBackground + source={require("../../assets/abstract.jpg")} + resizeMode="cover" + className="w-full h-full bg-no-repeat" + blurRadius={6} + > + <View className="items-center justify-center h-max"> + {receivedReviews ? ( + receivedReviews.length > 0 ? ( + <> + <FlatList + className="mt-2" + data={receivedReviews} + ItemSeparatorComponent={_separator} + keyExtractor={(item) => String(item.id)} + renderItem={({ item }) => <ReviewCard review={item} />} + /> + </> + ) : ( + <Text className="text-[25px] p-[11px] text-[#fff] font-semibold"> + Este producto no ha sido calificado por ningún comprador. + </Text> + ) + ) : null} + </View> + </ImageBackground> + ); +} diff --git a/src/screens/SellerReviews.tsx b/src/screens/SellerReviews.tsx new file mode 100644 index 0000000..ca2d9c8 --- /dev/null +++ b/src/screens/SellerReviews.tsx @@ -0,0 +1,134 @@ +import { useFocusEffect, useNavigation } from "@react-navigation/core"; +import React, { useEffect, useState } from "react"; +import { FlatList, ImageBackground, Text, View, TouchableOpacity, useWindowDimensions } from "react-native"; +import { Divider } from "react-native-paper"; +import { useColorScheme } from "nativewind"; +import { TUserReview } from "../../urubuy"; +import { StarRatingDisplay } from "react-native-star-rating-widget"; +import { getCustomerProfile } from "../services/Requests"; + +type ReviewUserCard = { + review: TUserReview; +}; + +type TReviewUsername = { + username: string; + reviewId: number; +}; + +export default function SellerReview(props: any) { + const [receivedUserReviews, setRecievedReviewsUser] = useState<TUserReview[] | undefined>(undefined); + const [reviewUsername, setReviewUsername] = useState<TReviewUsername[] | undefined>([]); + const { colorScheme } = useColorScheme(); + const dark = colorScheme === "dark"; + const nav = useNavigation(); + + useEffect(() => { + setRecievedReviewsUser(props.route.params.sellerReviews); + handleCustomer(props.route.params.sellerReviews); + }, []); + + const handleCustomer = (reviews: TUserReview[]) => { + let k: TReviewUsername[] = []; + + if (reviews && reviews.length > 0) { + reviews.forEach((r) => { + getCustomerProfile(r.customerEmail).then((res) => { + if (res.status === 200) { + if (reviewUsername?.find((y) => y.reviewId === +r.id) === undefined) + setReviewUsername((p) => [...p!, { username: res.data.username, reviewId: +r.id }]); + } + }); + }); + } + }; + + const Card: React.FC<ReviewUserCard> = ({ review }) => { + return ( + <View + className=" + ml-[2%] + mb-[10px] + w-[96%] + bg-[#fff] + dark:bg-dark-mode-bg + border-header-color rounded-[5px] border-[1.33px]" + > + <View className="flex-row justify-between"> + <Text className="text-[18px] p-[11px] items-start dark:text-dark-mode-text font-semibold"> + Fecha: {review.date} + </Text> + <View className="flex-row p-2"> + <StarRatingDisplay + rating={review.rating ? review?.rating : 1} + starStyle={{ marginHorizontal: -2 }} + color={dark ? "#cf8c40" : "blue"} + /> + </View> + </View> + <Divider style={dark ? { height: 1.5, backgroundColor: "white" } : { height: 1.5 }} /> + <View className="flex-row justify-between"> + <Text className="text-[18px] flex-wrap p-[5px] ml-6 mt-3 dark:text-dark-mode-text font-semibold"> + {review.description} + </Text> + </View> + <View className="flex-row"> + <Text className="text-[18px] p-[11px] dark:text-dark-mode-text font-semibold">Por: </Text> + <TouchableOpacity + onPress={() => + nav.navigate( + "UserProfile" as never, + { + email: review.customerEmail, + } as never, + ) + } + > + <Text className="text-[18px] p-[11px] text-header-color dark:text-[#f1c533] font-semibold"> + {reviewUsername && + reviewUsername.length > 0 && + reviewUsername?.map((x) => { + if (x.reviewId === +review.id) { + return x.username; + } + })} + </Text> + </TouchableOpacity> + </View> + </View> + ); + }; + + const _separator = () => { + return <Divider style={{ padding: 1.13, backgroundColor: "white", margin: 15 }} />; + }; + + return ( + <ImageBackground + source={require("../../assets/abstract.jpg")} + resizeMode="cover" + className="w-full h-full bg-no-repeat" + blurRadius={6} + > + <View className="items-center justify-center h-max"> + {receivedUserReviews ? ( + receivedUserReviews.length > 0 ? ( + <> + <FlatList + className="mt-2" + data={receivedUserReviews} + ItemSeparatorComponent={_separator} + keyExtractor={(item) => String(item.id)} + renderItem={({ item }) => <Card review={item} />} + /> + </> + ) : ( + <Text className="text-[25px] p-[11px] text-[#fff] font-semibold"> + Este vendedor no ha sido calificado por ningún comprador + </Text> + ) + ) : null} + </View> + </ImageBackground> + ); +} diff --git a/src/screens/ShoppingPost.tsx b/src/screens/ShoppingPost.tsx index ea84daa..dd19ca8 100644 --- a/src/screens/ShoppingPost.tsx +++ b/src/screens/ShoppingPost.tsx @@ -6,13 +6,14 @@ import SliderSlick from "../components/SliderSlick"; import { addToCart, getData, getSellerProfile, getShoppingPostById } from "../services/Requests"; import CustomReport, { ReportIOS } from "../components/Report/CustomReport"; import Loading from "../components/Loading"; -import { TShoppingPost } from "../../urubuy"; +import { TShoppingPost, TUserReview } from "../../urubuy"; import { Package, ShoppingCartSimple } from "phosphor-react-native"; import { StarRatingDisplay } from "react-native-star-rating-widget"; type SellerRating = { username: string; averageRating: number; + receivedUserReviews: TUserReview[]; }; export default function ShoppingPost(props: any) { @@ -20,7 +21,8 @@ export default function ShoppingPost(props: any) { const [shoppingPost, setShoppingPost] = useState<TShoppingPost | undefined>(undefined); const [promptAndroid, setPromptAndroid] = useState(false); const [activeUser, setActiveUser] = useState<string | undefined>(undefined); - const [seller, setSeller] = useState<SellerRating | undefined>(undefined); + const [sellerRating, setSellerRating] = useState<SellerRating | undefined>(undefined); + const [loading, setLoading] = useState(false); useEffect(() => { const unsubscribe = nav.addListener("blur", () => { @@ -30,12 +32,14 @@ export default function ShoppingPost(props: any) { }, [props]); useEffect(() => { + setLoading(true); getShoppingPostById(props.route.params.id) .then((res) => { setShoppingPost(res.data); handleShowSeller(res.data.sellerEmail); }) - .catch((err) => console.log(err.response.data)); + .catch((err) => console.log(err)) + .finally(() => setLoading(false)); const unsubscribe = nav.addListener("focus", () => { setShoppingPost(undefined); @@ -73,7 +77,11 @@ export default function ShoppingPost(props: any) { function handleShowSeller(email: string) { getSellerProfile(email).then((res) => { if (res.status === 200) { - setSeller({ username: res.data.username, averageRating: Math.floor(res.data.averageRating) }); + setSellerRating({ + username: res.data.username, + averageRating: Math.floor(res.data.averageRating), + receivedUserReviews: res.data.receivedUserReviews, + }); } }); } @@ -91,20 +99,28 @@ export default function ShoppingPost(props: any) { blurRadius={6} > <CustomReport android={promptAndroid} /> - {shoppingPost ? ( + {loading ? ( + <View className="flex mx-auto my-auto"> + <Loading text="Cargando publicación..." bg={true} /> + </View> + ) : shoppingPost ? ( <ScrollView showsVerticalScrollIndicator={false}> <View className="flex-row items-center justify-between"> <TouchableOpacity onPress={() => handleProfile(shoppingPost.sellerEmail)}> - <Text className="text-center font-bold text-[19px] mt-2 ml-5 text-gold-buy">{seller?.username!}</Text> + <Text className="text-center font-bold text-[19px] mt-2 ml-5 text-gold-buy"> + {sellerRating?.username!} + </Text> </TouchableOpacity> <TouchableOpacity className={Platform.OS === "android" ? "mr-3" : ""} - onPress={() => alert("todo: calificaciones del seller")} + onPress={() => + nav.navigate("SellerReviews" as never, { sellerReviews: sellerRating?.receivedUserReviews } as never) + } > <View className="mt-2 mr-5"> <StarRatingDisplay - rating={seller?.averageRating ? seller?.averageRating : 1} + rating={sellerRating?.averageRating ? sellerRating?.averageRating : 1} starStyle={{ marginHorizontal: -2 }} color="#cf8c40" starSize={23} @@ -165,13 +181,27 @@ export default function ShoppingPost(props: any) { Peso: {shoppingPost.weight} kg </Text> </View> + <Text className="flex-wrap p-3 -mb-6 -mt-3 font-semibold text-[17px] text-dark-mode-text"> + {shoppingPost.stock + ? shoppingPost.stock > 10 + ? "¡Stock disponible!" + : shoppingPost.stock > 5 + ? "¡¡¡Ultimas unidades!!!" + : shoppingPost.stock === 0 + ? "Producto sin stock" + : null + : null} + </Text> <Text className="flex-wrap mt-3 p-3 font-semibold text-[17px] text-dark-mode-text"> {shoppingPost.description} </Text> <TouchableOpacity className={Platform.OS === "android" ? "ml-5" : ""} - onPress={() => alert("todo: calificaciones del producto")} + onPress={() => { + console.log(shoppingPost.reviews.length); + nav.navigate("ProductReviews" as never, { reviews: shoppingPost.reviews } as never); + }} > <View className="flex-row mt-2 ml-5"> <StarRatingDisplay @@ -233,7 +263,9 @@ export default function ShoppingPost(props: any) { </ScrollView> ) : ( <View className="flex mx-auto my-auto"> - <Loading text="Cargando publicación..." bg={true} /> + <Text className="text-center text-[20px] font-bold text-dark-mode-text"> + Ha ocurrido un problema, lo sentimos + </Text> </View> )} </ImageBackground> diff --git a/src/screens/UserProfile.tsx b/src/screens/UserProfile.tsx index bfd3453..a37a0f1 100644 --- a/src/screens/UserProfile.tsx +++ b/src/screens/UserProfile.tsx @@ -25,11 +25,20 @@ function UserProfile(props: any) { const unsuscribe = nav.addListener("focus", () => { setReviews([]); getInitialData(); - setShowReviews(false); }); return unsuscribe; }, [props]); + useEffect(() => { + const unsuscribe = nav.addListener("blur", () => { + setReviews([]); + setShowReviews(false); + setSeller(undefined); + setCustomer(undefined); + }); + return unsuscribe; + }, []); + const getInitialData = async () => { setLoading(true); @@ -42,7 +51,6 @@ function UserProfile(props: any) { } else console.error("err getting s profile"); }) .catch((err) => { - console.log(err.response.data); if (seller === undefined) { getCustomerProfile(props.route.params.email) .then((res) => { @@ -64,7 +72,7 @@ function UserProfile(props: any) { }); }; - const renderProfile = (user: TCustomer | TSeller) => { + const renderSeller = (user: TSeller) => { return ( <> {user?.picture !== undefined && user?.picture !== "" && user?.picture !== null ? ( @@ -80,19 +88,61 @@ function UserProfile(props: any) { <Image source={require("../../assets/placeholder.png")} resizeMode="contain" - className="w-[150px] h-[250px] ml-3" + className="w-[137px] h-[137px] mt-[35px] ml-3 rounded-full" /> )} <View className="max-h-[250px] max-w-[250px] absolute top-[70] left-[160] border-[black]"> <Text className="text-[black] dark:text-dark-mode-text text-[20px] font-semibold ml-[15px]"> - {(user as TSeller) ? (user as TSeller).firstName + " " + (user as TSeller).lastName : null} + {user.firstName + " " + user.lastName} </Text> - <Text className="text-[black] dark:text-dark-mode-text text-[15px] font-semibold ml-[15px] mt-[15px] p-[1]"> - {user?.email} + <View className="mt-3 ml-4"> + <StarRatingDisplay + rating={user?.averageRating ? user?.averageRating : 1} + starStyle={{ marginHorizontal: -2 }} + color={dark ? "#cf8c40" : "blue"} + /> + </View> + </View> + + <CustomButton + onPress={() => setShowReviews(!showReviews)} + value={"Ver calificaciones"} + style={undefined} + isDisabled={false} + /> + <View className="left-[72px] bottom-7"> + <Star size={20} color="white" weight="duotone" /> + </View> + </> + ); + }; + + const renderCustomer = (user: TCustomer) => { + return ( + <> + {user?.picture !== undefined && user?.picture !== "" && user?.picture !== null ? ( + <Image + source={ + user?.picture.includes("data:image") + ? { uri: user?.picture } + : { uri: `data:image/jpg;base64,${user?.picture}` } + } + className="w-[150px] h-[150px] mt-[35px] ml-3 rounded-full" + /> + ) : ( + <Image + source={require("../../assets/placeholder.png")} + resizeMode="contain" + className="w-[137px] h-[137px] mt-[35px] ml-3 rounded-full" + /> + )} + <View className="max-h-[250px] max-w-[250px] absolute top-[70] left-[160] border-[black]"> + <Text className="text-[black] dark:text-dark-mode-text text-[20px] font-semibold ml-[15px]"> + {user.username} </Text> <View className="mt-3 ml-4"> <StarRatingDisplay - rating={seller?.averageRating ? seller?.averageRating : 1} + rating={user?.averageRating ? user?.averageRating : 1} starStyle={{ marginHorizontal: -2 }} color={dark ? "#cf8c40" : "blue"} /> @@ -191,9 +241,9 @@ function UserProfile(props: any) { <Loading text="Cargando perfil" bg={true} /> </View> ) : customer ? ( - renderProfile(customer) + renderCustomer(customer) ) : seller ? ( - renderProfile(seller) + renderSeller(seller as TSeller) ) : null} {showReviews ? ( reviews && reviews.length > 0 ? ( diff --git a/src/screens/customer/Checkout.tsx b/src/screens/customer/Checkout.tsx index 9e6084e..31243c0 100644 --- a/src/screens/customer/Checkout.tsx +++ b/src/screens/customer/Checkout.tsx @@ -18,7 +18,7 @@ export default function Checkout(props: any) { const nav = useNavigation(); const [errorMessage, setErrorMessage] = useState(""); const [successMessage, setSuccessMessage] = useState(""); - const urlPay = Constants.manifest?.extra?.URL_CLOUD + "paypal/pay/"; + const urlPay = Constants.manifest?.extra?.URL_LOCAL + "paypal/pay/"; const [shoppingCartId, setShoppingCartId] = useState<string | undefined>(""); const [checkout, setCheckout] = useState<TCheckoutResponse | undefined>(undefined); const [loadingRedirect, setLoadingRedirect] = useState(false); diff --git a/src/screens/customer/GiveReview.tsx b/src/screens/customer/GiveReview.tsx index ed03bef..155cd3f 100644 --- a/src/screens/customer/GiveReview.tsx +++ b/src/screens/customer/GiveReview.tsx @@ -1,16 +1,16 @@ import { useFocusEffect, useNavigation } from "@react-navigation/core"; import { ChatCircleDots, ImageSquare, PencilSimple, Star, UserCircle, X, XCircle } from "phosphor-react-native"; import React, { useEffect, useState } from "react"; -import { View, Text, TouchableOpacity, Modal, Image, ScrollView, Alert, Platform } from "react-native"; +import { View, Text, TouchableOpacity, Modal, Image, ScrollView, Alert, Platform, ImageBackground } from "react-native"; import { useColorScheme } from "nativewind"; import * as ImagePicker from "expo-image-picker"; import CustomButton from "../../components/CustomButton"; import SliderSlick from "../../components/SliderSlick"; -import { TReview, TUserReview } from "../../../urubuy"; +import { minShoppingPost, TCustomer, TPurchase, TReview, TShoppingCart, TUserReview } from "../../../urubuy"; import { Divider, TextInput } from "react-native-paper"; import Loading from "../../components/Loading"; import myStyle from "../../../assets/styles"; -import { getData, getSellerProfile, reviewSeller } from "../../services/Requests"; +import { getCustomerProfile, getData, getSellerProfile, reviewProduct, reviewSeller } from "../../services/Requests"; import StarRating from "react-native-star-rating-widget"; type GReview = { @@ -19,7 +19,7 @@ type GReview = { }; export default function GiveReview(props: any) { - const [purchaseId, setPurchaseId] = useState(-1); + const [purchase, setPurchase] = useState<TPurchase | undefined>(undefined); const [showReviewSeller, setShowReviewSeller] = useState(false); const [showReviewProduct, setShowReviewProduct] = useState(false); const [loading, setLoading] = useState(false); @@ -32,18 +32,23 @@ export default function GiveReview(props: any) { const [inputHeight, setInputHeight] = useState(0); const [email, setEmail] = useState(""); const [sellerEmail, setSellerEmail] = useState(""); + const [user, setUser] = useState<TCustomer | undefined>(undefined); const [sellerUsername, setSellerUsername] = useState(""); + const [sellerReviewed, setSellerReviewed] = useState(false); + const [activeProduct, setActiveProduct] = useState<minShoppingPost | undefined>(undefined); const nav = useNavigation(); useFocusEffect(() => { - setPurchaseId(props.route.params.id); + setPurchase(props.route.params.purchase); + setUser(props.route.params.user); fetchSellerUsername(props.route.params.seller); setSellerEmail(props.route.params.seller); + setSellerReviewed(props.route.params.sReviewed); }); useEffect(() => { getInitialData(); - }, []); + }, [user]); const fetchSellerUsername = async (seller: string) => { getSellerProfile(seller).then((res) => { @@ -62,7 +67,8 @@ export default function GiveReview(props: any) { setShowReviewSeller(!showReviewSeller); }; - const handleProduct = () => { + const handleProduct = (product: minShoppingPost) => { + setActiveProduct(product); setShowReviewProduct(!showReviewProduct); }; @@ -106,6 +112,7 @@ export default function GiveReview(props: any) { customerEmail: email, sellerEmail: sellerEmail, from: "CUSTOMER", + purchaseId: +purchase?.id!, }; reviewSeller(sellerReview) .then((res) => { @@ -116,20 +123,34 @@ export default function GiveReview(props: any) { }) .finally(() => { setReviewComment(""); + setSellerReviewed(true); setImages([]); setDefaultRating(3); showReviewProduct ? setShowReviewProduct(!showReviewProduct) : setShowReviewSeller(!showReviewSeller); }); } else { - let review: TReview = { + let review = { id: "", rating: defaultRating, description: reviewComment, base64Images: images!, date: "", customerEmail: email, - sellerEmail: sellerEmail, + shoppingPostId: activeProduct!.id, }; + reviewProduct(review) + .then((res) => { + if (res.status === 200) Alert.alert("Gracias por calificar"); + }) + .catch((err) => { + Alert.alert("Imposible calificar", err.response.data); + }) + .finally(() => { + setReviewComment(""); + setImages([]); + setDefaultRating(3); + showReviewProduct ? setShowReviewProduct(!showReviewProduct) : setShowReviewSeller(!showReviewSeller); + }); } }; @@ -140,45 +161,65 @@ export default function GiveReview(props: any) { return ( <> - <View className="flex-1 dark:bg-dark-mode-bg "> - <Text className="mt-5 mr-7 p-2 text-[45px] font-extrabold text-[#000] dark:text-dark-mode-text"> - Calificaciones - </Text> + <ImageBackground + source={require("../../../assets/abstract.jpg")} + resizeMode="cover" + className="w-full h-full bg-no-repeat" + blurRadius={6} + > + <View className="flex-1"> + <Text className="mt-5 mr-7 p-2 text-[45px] font-extrabold text-dark-mode-text">Calificaciones</Text> + <Divider style={{ height: 1.3, backgroundColor: "white" }} /> - <View className="border-header-color dark:border-gold-buy border-[1.33px] p-3 m-2"> - <View className="flex-row"> - <Text className="p-2 text-lg font-semibold dark:text-dark-mode-text">Calificar compra del vendedor:</Text> - <TouchableOpacity className="flex-1" onPress={() => sellerClicked()}> - <Text className="flex-wrap p-2 text-lg font-semibold text-header-color dark:text-gold-buy "> - {sellerUsername} - </Text> - </TouchableOpacity> - </View> - <Text className="p-2 text-lg font-semibold text-center dark:text-dark-mode-text"> - COMPRA ID: {purchaseId} - </Text> - <View className="justify-center m-2"> - <CustomButton - onPress={() => handleProduct()} - value={"Calificar producto"} - style={undefined} - isDisabled={false} - /> - <View className="left-[57px] bottom-7"> - <PencilSimple size={19} color={"white"} weight="duotone" /> + <View className="border-header-color border-[1.33px] p-3 m-2 mt-[20px] bg-dark-mode-text dark:bg-dark-mode-bg"> + <View className="flex-row"> + <Text className="p-2 text-lg font-semibold dark:text-dark-mode-text">Calificar compra del vendedor:</Text> + <TouchableOpacity className="flex-1" onPress={() => sellerClicked()}> + <Text className="flex-wrap p-2 text-lg font-semibold text-gold-buy ">{sellerUsername}</Text> + </TouchableOpacity> </View> - <CustomButton - onPress={() => handleSeller()} - value={"Calificar vendedor"} - style={undefined} - isDisabled={false} - /> - <View className="left-[57px] bottom-7"> - <UserCircle size={19} color={"white"} weight="duotone" /> + <Text className="p-2 text-lg font-semibold dark:text-dark-mode-text">Productos de la compra</Text> + {purchase && + purchase.shoppingPosts && + purchase.shoppingPosts.length > 0 && + purchase.shoppingPosts.map((p) => ( + <View className="flex-row flex-wrap"> + <TouchableOpacity onPress={() => handleProduct(p)}> + <Text className="p-1 text-lg font-semibold text-gold-buy">{"‣ " + p.title}</Text> + </TouchableOpacity> + </View> + ))} + + <View className="justify-center m-2"> + {!sellerReviewed ? ( + <> + <CustomButton + onPress={() => handleSeller()} + value={"Calificar vendedor"} + style={undefined} + isDisabled={false} + /> + <View className="left-[57px] bottom-7"> + <UserCircle size={19} color={"white"} weight="duotone" /> + </View> + </> + ) : ( + <> + <CustomButton + onPress={undefined} + value={"Vendedor ya calificado"} + style={undefined} + isDisabled={true} + /> + <View className="left-[57px] bottom-7"> + <UserCircle size={19} color={"white"} weight="duotone" /> + </View> + </> + )} </View> </View> </View> - </View> + </ImageBackground> {showReviewSeller || showReviewProduct ? ( <View className="dark:bg-dark-mode-bg"> <View className="items-center justify-center flex-1 mt-6"> @@ -217,7 +258,7 @@ export default function GiveReview(props: any) { setReviewComment(""); setLoading(false); setDefaultRating(3); - + setActiveProduct(undefined); showReviewProduct ? setShowReviewProduct(!showReviewProduct) : setShowReviewSeller(!showReviewSeller); @@ -225,8 +266,10 @@ export default function GiveReview(props: any) { > <XCircle size={25} weight="regular" color={colorScheme === "dark" ? "white" : "black"} /> </TouchableOpacity> - <Text className="text-lg font-semibold dark:text-dark-mode-text"> - {showReviewProduct ? "Calificar producto" : `Calificar vendedor: ${sellerEmail}`} + <Text className="text-lg font-semibold text-center dark:text-dark-mode-text"> + {showReviewProduct + ? `Calificar producto: ${activeProduct?.title}` + : `Calificar vendedor: ${sellerEmail}`} </Text> <Divider style={dark ? { height: 2, backgroundColor: "white" } : { height: 2, backgroundColor: "#32377B" }} @@ -298,6 +341,7 @@ export default function GiveReview(props: any) { setReviewComment(""); setLoading(false); setDefaultRating(3); + setActiveProduct(undefined); showReviewProduct ? setShowReviewProduct(!showReviewProduct) : setShowReviewSeller(!showReviewSeller); diff --git a/src/screens/customer/Profile.tsx b/src/screens/customer/Profile.tsx index a37c832..f7991a9 100644 --- a/src/screens/customer/Profile.tsx +++ b/src/screens/customer/Profile.tsx @@ -19,16 +19,18 @@ function Profile() { const dark = colorScheme === "dark"; const [loading, setLoading] = useState(false); - useFocusEffect(() => { - getInitialData(); - }); - useEffect(() => { - const unsuscribe = nav.addListener("blur", () => { - setUser(undefined); + const unsuscribe = nav.addListener("focus", () => { + getInitialData(); }); return unsuscribe; - }, []); + }, []), + useEffect(() => { + const unsuscribe = nav.addListener("blur", () => { + setUser(undefined); + }); + return unsuscribe; + }, []); const getInitialData = async () => { let email = (await getData("email")) as string; @@ -43,6 +45,7 @@ function Profile() { picture: res.data.picture, givenUserReviews: res.data.givenUserReviews, receivedUserReviews: res.data.receivedUserReviews, + givenReviews: res.data.givenReviews, purchases: res.data.purchases, }; setUser(myUser); @@ -178,14 +181,22 @@ function Profile() { {loading ? ( <View className="mx-auto my-auto"> - <Loading text="Enviando mail..." bg={true} /> + <Loading text="Enviando mail..." bg={dark ? true : false} /> </View> ) : ( <View className="my-8"> <TouchableOpacity> <CustomButton isDisabled={false} - onPress={() => nav.navigate("Purchases" as never, { purchases: user?.purchases } as never)} + onPress={() => + nav.navigate( + "Purchases" as never, + { + user: user, + purchases: user?.purchases, + } as never, + ) + } value={"Mis compras"} style={undefined} /> @@ -205,7 +216,11 @@ function Profile() { onPress={() => { nav.navigate( "Reviews" as never, - { givenReviews: user?.givenUserReviews, receivedUserReviews: user?.receivedUserReviews } as never, + { + givenUserReviews: user?.givenUserReviews, + receivedUserReviews: user?.receivedUserReviews, + givenReviews: user?.givenReviews, + } as never, ); }} value={"Mis calificaciones"} diff --git a/src/screens/customer/Purchase.tsx b/src/screens/customer/Purchase.tsx index 522667b..32f0a9e 100644 --- a/src/screens/customer/Purchase.tsx +++ b/src/screens/customer/Purchase.tsx @@ -1,108 +1,132 @@ import { useFocusEffect, useNavigation } from "@react-navigation/core"; import React, { useEffect, useState } from "react"; -import { FlatList, ImageBackground, Image, Text, View, Platform } from "react-native"; +import { FlatList, ImageBackground, Image, Text, View, Platform, Touchable } from "react-native"; import { Divider } from "react-native-paper"; import { useColorScheme } from "nativewind"; import { Star } from "phosphor-react-native"; import CustomButton from "../../components/CustomButton"; -import { TPurchase, TSeller } from "../../../urubuy"; +import { TCustomer, TPurchase, TReview, TSeller, TUserReview } from "../../../urubuy"; +import { TouchableOpacity } from "react-native-gesture-handler"; type PurchaseCard = { purchase: TPurchase; }; +type CustomShow = { + purchaseId: number; + show: boolean; +}; + +export const handleStatus = (status: string) => { + let s = ""; + status === "PREPARING_ORDER" + ? (s = "En preparación") + : status === "OUT_FOR_DELIVERY" + ? (s = "En camino") + : status === "READY_FOR_PICKUP" + ? (s = "Listo para retirar") + : status === "DELIVERED" + ? (s = "Entregado") + : (s = "Indefinido"); + return s; +}; + export default function Purchase(props: any) { const nav = useNavigation(); const [purchases, setPurchases] = useState<TPurchase[] | undefined>(undefined); const { colorScheme } = useColorScheme(); + const [user, setUser] = useState<TCustomer | undefined>(undefined); const dark = colorScheme === "dark"; useEffect(() => { - setPurchases(props.route.params.purchases); + const unsubscribe = nav.addListener("focus", () => { + let u = props.route.params.user as TCustomer; + setUser(u); + setPurchases(props.route.params.purchases); + }); + return unsubscribe; + }, [props]); + + useEffect(() => { + const unsubscribe = nav.addListener("blur", () => { + setPurchases([]); + }); + return unsubscribe; }, [props]); const handleReviewing = (purchaseId: string, seller: string) => { + let sReviewed: boolean = false; + let p = purchases?.find((x) => x.id === purchaseId); + if (p) + p.customerReview && p.customerReview.customerEmail === user?.email ? (sReviewed = true) : (sReviewed = false); + nav.navigate( - "ReviewSeller" as never, + "GiveReview" as never, { - id: `${purchaseId}`, + purchase: p, + user: user, seller: seller, + sReviewed: sReviewed, } as never, ); }; - const handleStatus = (status: string) => { - let s = ""; - status === "PREPARING_ORDER" - ? (s = "En preparacion") - : status === "OUT_FOR_DELIVERY" - ? (s = "Listo para delivery") - : status === "READY_FOR_PICKUP" - ? (s = "Listo para retirar") - : status === "DELIVERED" - ? (s = "Entregado") - : (s = "Indefinido"); - return s; - }; - - function formatted_date(d: Date) { - var result = ""; - result += d.getFullYear() + "/" + (d.getMonth() + 1) + "/" + d.getDate(); - return result; - } const Card: React.FC<PurchaseCard> = ({ purchase }) => { return ( <View className=" ml-[2%] mb-[10px] - w-[96%] - min-h-[200px] + w-[96%] bg-[#ffffff] dark:bg-dark-mode-bg border-header-color rounded-md border-[1.13px]" > - <View className="flex-row-reverse flex-1"> + <View className="flex-row-reverse justify-between"> <Text className="text-[18px] p-[11px] flex-wrap dark:text-dark-mode-text font-semibold"> Status: {handleStatus(purchase.status)} </Text> - <Text className="text-[18px] p-[12px] mr-4 dark:text-dark-mode-text font-semibold"> - {purchase.date - ? Platform.OS === "android" - ? purchase.date - : "Fecha: " + purchase.date - : "Fecha: " + formatted_date(new Date())} + <Text className="text-[18px] p-[12px] dark:text-dark-mode-text font-semibold"> + {Platform.OS === "android" ? purchase.date : "Fecha: " + purchase.date} </Text> </View> <Divider style={dark ? { height: 1.5, backgroundColor: "white" } : { height: 1.5 }} /> <View className="flex-row justify-between"> - <Text className="text-[18px] p-[11px] dark:text-dark-mode-text font-semibold">{purchase.sellerEmail}</Text> + <View className="flex-row"> + <Text className="text-[18px] p-[11px] dark:text-dark-mode-text font-semibold">Vendedor:</Text> + <TouchableOpacity + onPress={() => nav.navigate("UserProfile" as never, { email: purchase.sellerEmail } as never)} + > + <Text className="text-[18px] p-[11px] text-gold-buy font-semibold">{purchase.sellerEmail}</Text> + </TouchableOpacity> + </View> <Text className="text-[18px] p-[11px] mb-[-5px] dark:text-dark-mode-text font-semibold"> USD {purchase.total} </Text> </View> - - <View className="flex-row"> - <Image - source={require("../../../assets/bgColorful.jpg")} - className="max-h-[90%] max-w-[39%] h-[155px] ml-2" - resizeMode="contain" - /> - <CustomButton - value={"Calificar"} - style={{ width: "40%", margin: 35 }} - onPress={() => handleReviewing(purchase.id, purchase.sellerEmail)} - isDisabled={false} - /> - <View - className={Platform.select({ - ios: "absolute right-[142px] mt-[58px]", - android: "absolute right-[136px] mt-[57px]", - })} - > - <Star size={21} color="white" /> + {purchase.shoppingPosts.map((x, i) => ( + <Text key={i} className="text-[18px] p-[11px] text-right dark:text-dark-mode-text font-semibold"> + {i + 1 + ": " + x.title} + </Text> + ))} + {purchase.status === "DELIVERED" && ( + <View className="flex-row"> + <CustomButton + value={"Calificar"} + style={{ width: "40%", margin: 35, right: -70 }} + onPress={() => handleReviewing(purchase.id, purchase.sellerEmail)} + isDisabled={false} + /> + <View + className={Platform.select({ + ios: "absolute left-[116px] mt-[25px]", + android: "absolute left-[109px] mt-[24px]", + })} + > + <Star size={21} color="white" /> + </View> </View> - </View> + )} </View> ); }; @@ -123,7 +147,9 @@ export default function Purchase(props: any) { renderItem={({ item }) => <Card purchase={item} />} /> ) : ( - <Text className="text-[18px] p-[11px] dark:text-dark-mode-text font-semibold">No has realizado compras</Text> + <Text className="text-[25px] p-[11px] mx-auto my-auto dark:text-dark-mode-text font-semibold"> + No has realizado compras + </Text> )} </ImageBackground> </> diff --git a/src/screens/customer/Review.tsx b/src/screens/customer/Review.tsx index 9301e64..916b669 100644 --- a/src/screens/customer/Review.tsx +++ b/src/screens/customer/Review.tsx @@ -3,24 +3,26 @@ import React, { useEffect, useState } from "react"; import { FlatList, ImageBackground, Text, View, TouchableOpacity, useWindowDimensions } from "react-native"; import { Divider } from "react-native-paper"; import { useColorScheme } from "nativewind"; -import { TUserReview } from "../../../urubuy"; -import Loading from "../../components/Loading"; +import { TUserReview, TReview } from "../../../urubuy"; import { StarRatingDisplay } from "react-native-star-rating-widget"; -import {} from "react-native"; import { TabView, SceneMap, TabBar } from "react-native-tab-view"; +import SliderSlick from "../../components/SliderSlick"; type ReviewUserCard = { review: TUserReview; }; +type ReviewCard = { + review: TReview; +}; + export default function Review(props: any) { const nav = useNavigation(); const [givenReviewsUser, setGivenReviewsUser] = useState<TUserReview[] | undefined>(undefined); const [receivedUserReviews, setRecievedReviewsUser] = useState<TUserReview[] | undefined>(undefined); - + const [givenReviews, setGivenReviews] = useState<TReview[] | undefined>(undefined); const { colorScheme } = useColorScheme(); const dark = colorScheme === "dark"; - const layout = useWindowDimensions(); const [index, setIndex] = React.useState(0); @@ -38,20 +40,26 @@ export default function Review(props: any) { blurRadius={6} > <View className="items-center justify-center h-max"> - {receivedUserReviews && receivedUserReviews.length > 0 ? ( - <> - <FlatList - ListHeaderComponent={ - <Text className="text-[35px] p-[11px] text-dark-mode-text font-semibold"> - Calificaciones recibidas por vendedores - </Text> - } - className="mt-2" - data={receivedUserReviews} - keyExtractor={(item) => String(item.id)} - renderItem={({ item }) => <Card review={item} />} - /> - </> + {receivedUserReviews ? ( + receivedUserReviews.length > 0 ? ( + <> + <FlatList + ListHeaderComponent={ + <Text className="text-[35px] p-[11px] text-dark-mode-text font-semibold"> + Calificaciones recibidas por vendedores + </Text> + } + className="mt-2" + data={receivedUserReviews} + keyExtractor={(item) => String(item.id)} + renderItem={({ item }) => <Card review={item} />} + /> + </> + ) : ( + <Text className="text-[25px] p-[11px] text-[#fff] font-semibold"> + No ha sido calificado por ningún vendedor + </Text> + ) ) : null} </View> </ImageBackground> @@ -64,7 +72,7 @@ export default function Review(props: any) { className="w-full h-full bg-no-repeat" blurRadius={6} > - <View className="items-center justify-center h-max"> + <View className="items-center justify-center h-max w-max"> {givenReviewsUser ? ( givenReviewsUser.length > 0 ? ( <FlatList @@ -79,19 +87,42 @@ export default function Review(props: any) { renderItem={({ item }) => <Card review={item} />} /> ) : ( - <Text className="text-[18px] p-[11px] text-[#fff] font-semibold"> - No ha calificado a ningun usuario y/o producto - </Text> + <Text className="text-[25px] p-[11px] text-[#fff] font-semibold">No ha calificado a ningún vendedor</Text> ) ) : null} </View> </ImageBackground> ); - const _givenReviews = (jumpTo: any) => ( - <View style={{ flex: 1 }}> - <Text>Third Route</Text> - </View> + const _givenReviews = () => ( + <ImageBackground + source={require("../../../assets/abstract.jpg")} + resizeMode="cover" + className="w-full h-full bg-no-repeat" + blurRadius={6} + > + <View className="items-center justify-center h-max"> + {givenReviews ? ( + givenReviews.length > 0 ? ( + <> + <FlatList + ListHeaderComponent={ + <Text className="text-[35px] p-[11px] text-dark-mode-text font-semibold"> + Calificaciones dadas a productos + </Text> + } + className="mt-2" + data={givenReviews} + keyExtractor={(item) => String(item.id)} + renderItem={({ item }) => <ReviewCard review={item} />} + /> + </> + ) : ( + <Text className="text-[25px] p-[11px] text-[#fff] font-semibold">No ha calificado ningún producto</Text> + ) + ) : null} + </View> + </ImageBackground> ); const renderScene = SceneMap({ @@ -101,8 +132,9 @@ export default function Review(props: any) { }); useEffect(() => { - setGivenReviewsUser(props.route.params.givenReviews); + setGivenReviewsUser(props.route.params.givenUserReviews); setRecievedReviewsUser(props.route.params.receivedUserReviews); + setGivenReviews(props.route.params.givenReviews); }, [props]); const handleProfileSeller = (seller: string) => { @@ -114,6 +146,15 @@ export default function Review(props: any) { ); }; + const handleProductClicked = (productId: string) => { + nav.navigate( + "ShoppingPost" as never, + { + id: productId, + } as never, + ); + }; + const Card: React.FC<ReviewUserCard> = ({ review }) => { return ( <View @@ -121,13 +162,13 @@ export default function Review(props: any) { ml-[2%] mb-[10px] w-[96%] - bg-[#ffffff] + bg-[#fff] dark:bg-dark-mode-bg border-header-color rounded-[5px] border-[1.33px]" > <View className="flex-row justify-between"> <Text className="text-[18px] p-[11px] items-start dark:text-dark-mode-text font-semibold"> - Fecha: {Date.now()} + Fecha: {review.date} </Text> <View className="flex-row p-2"> <StarRatingDisplay @@ -155,6 +196,49 @@ export default function Review(props: any) { ); }; + const ReviewCard: React.FC<ReviewCard> = ({ review }) => { + return ( + <View + className=" + ml-[2%] + mb-[10px] + w-[96%] + bg-[#fff] + dark:bg-dark-mode-bg + border-header-color rounded-[5px] border-[1.33px]" + > + <View className="flex-row justify-between"> + <Text className="text-[18px] p-[11px] items-start dark:text-dark-mode-text font-semibold"> + Fecha: {review.date} + </Text> + <View className="flex-row p-2"> + <StarRatingDisplay + rating={review.rating ? review?.rating : 1} + starStyle={{ marginHorizontal: -2 }} + color={dark ? "#cf8c40" : "blue"} + /> + </View> + </View> + <Divider style={dark ? { height: 1.5, backgroundColor: "white" } : { height: 1.5 }} /> + <TouchableOpacity onPress={() => handleProductClicked(review.shoppingPost.id)}> + <Text className="text-[18px] p-[11px] text-header-color dark:text-[#f1c533] font-semibold"> + {review.shoppingPost.title} + </Text> + </TouchableOpacity> + <View className="flex-row justify-between"> + <Text className="text-[18px] flex-wrap p-[5px] ml-6 mt-3 dark:text-dark-mode-text font-semibold"> + {review.description} + </Text> + </View> + {review.base64Images && ( + <View className="p-2 scale-50 -mb-28 -mt-28"> + <SliderSlick pictures={review.base64Images} /> + </View> + )} + </View> + ); + }; + return ( <ImageBackground source={require("../../../assets/abstract.jpg")} @@ -168,13 +252,13 @@ export default function Review(props: any) { onIndexChange={setIndex} swipeEnabled={true} animationEnabled={true} - pagerStyle={{ backgroundColor: "white" }} - initialLayout={{ width: layout.width, height: layout.height }} + initialLayout={{ width: layout.width }} style={{ backgroundColor: "#fff" }} renderTabBar={(props) => ( <TabBar {...props} activeColor="#0c35c5" + inactiveColor="#501728" indicatorStyle={{ backgroundColor: "#0c35c5" }} labelStyle={{ fontSize: 16, fontWeight: "bold" }} style={{ backgroundColor: "white" }} @@ -183,55 +267,4 @@ export default function Review(props: any) { /> </ImageBackground> ); - /*<> - - <View className="items-center justify-center my-auto"> - {receivedUserReviews && receivedUserReviews.length > 0 ? ( - <> - <FlatList - ListHeaderComponent={ - <Text className="text-[35px] p-[11px] text-dark-mode-text font-semibold"> - Calificaciones recibidas por vendedores - </Text> - } - className="mt-2" - data={receivedUserReviews} - keyExtractor={(item) => String(item.id)} - ListFooterComponent={ - givenReviewsUser ? ( - givenReviewsUser.length > 0 ? ( - <FlatList - className="mt-2" - ListHeaderComponent={ - <Text className="text-[35px] p-[11px] text-dark-mode-text font-semibold"> - Calificaciones dadas a vendedores - </Text> - } - data={givenReviewsUser} - keyExtractor={(item) => String(item.id)} - renderItem={({ item }) => <Card review={item} />} - /> - ) : ( - <Text className="text-[18px] p-[11px] text-[#fff] font-semibold"> - No ha calificado a ningun usuario y/o producto - </Text> - ) - ) : ( - <Text className="text-[18px] p-[11px] text-[#fff] font-semibold"> - Todavia no ha recibido calificaciones - </Text> - ) - } - renderItem={({ item }) => <Card review={item} />} - /> - </> - ) : ( - <Text className="text-[18px] p-[11px] text-[#fff] font-semibold"> - Todavia no ha recibido calificaciones - </Text> - )} - </View> - </ImageBackground> - </> - );*/ } diff --git a/src/screens/customer/Settings.tsx b/src/screens/customer/Settings.tsx index 7dfa4d6..9997904 100644 --- a/src/screens/customer/Settings.tsx +++ b/src/screens/customer/Settings.tsx @@ -16,17 +16,15 @@ import Constants from "expo-constants"; import { Buffer } from "buffer"; import { ArrowFatLinesRight, - ArrowRight, - Backpack, BellRinging, BugBeetle, Check, CircleHalf, Moon, Password, + PauseCircle, Sun, Swap, - Trash, X, XCircle, } from "phosphor-react-native"; @@ -34,9 +32,15 @@ import { Appearance } from "react-native"; import { useColorScheme } from "nativewind"; import CustomReport, { ReportIOS } from "../../components/Report/CustomReport"; import CustomInput from "../../components/CustomInput"; -import { getData, login, storeData, suspendAccount } from "../../services/Requests"; +import { + getCustomerProfile, + getData, + login, + suspendAccount, + toggleSettingNotifications, +} from "../../services/Requests"; import { useFocusEffect, useNavigation } from "@react-navigation/core"; -import Logout, { removeDataStored } from "./Logout"; +import { removeDataStored } from "./Logout"; import { TUserKC } from "../../../urubuy"; import Loading from "../../components/Loading"; @@ -58,6 +62,7 @@ function Settings() { const [activeUser, setActiveUser] = useState<string | undefined>(undefined); const nav = useNavigation(); const [loading, setLoading] = useState(false); + const [ntfEnabled, setNtfEnabled] = useState(false); const getUserActive = async () => { return await getData("email"); @@ -71,7 +76,19 @@ function Settings() { }, []); useFocusEffect(() => { - getUserActive().then((res) => setActiveUser(res as string)); + getUserActive().then((res) => { + setActiveUser(res as string); + if (res) { + getCustomerProfile(res as string) + .then((res) => { + setNtfEnabled(res.data.notificationsEnabled); + }) + .catch((err) => { + console.log(err.response.data); + alert("error al obtener perfil de usuario"); + }); + } + }); }); const requestDarkTheme = () => { @@ -144,11 +161,15 @@ function Settings() { .finally(() => setLoading(false)); }; - const [userNotification, setUserNotification] = useState(false); - const handleNotifications = async (value: boolean) => { - setUserNotification(value); - await storeData("userNotification", String(value)); // store in backend and prevent sending + toggleSettingNotifications(activeUser!) + .then((res: any) => { + if (res.status === 200) { + let r = res.data as boolean; + setNtfEnabled(r); + } + }) + .catch((e) => console.log(e)); }; return ( @@ -188,8 +209,8 @@ function Settings() { Notificaciones </Text> <Switch - value={userNotification} - onChange={() => handleNotifications(!userNotification)} + value={ntfEnabled} + onChange={() => handleNotifications(!ntfEnabled)} className={Platform.OS === "ios" ? "absolute top-[3px] scale-[.85] right-1" : ""} /> </View> @@ -248,8 +269,8 @@ function Settings() { onPress={handleDeleteAccount} className="p-2 h-10 flex-row bg-[#ff0000] dark:bg-[#ff0000] border-[white] border-[1.33px] m-5 rounded-2xl" > - <Trash weight="fill" size={19} color="white" /> - <Text className="text-[#fff] text-[17px] font-bold mx-auto my-auto">Eliminar mi cuenta</Text> + <PauseCircle weight="fill" size={19} color="white" /> + <Text className="text-[#fff] text-[17px] font-bold mx-auto my-auto">Suspender mi cuenta</Text> </TouchableOpacity> </View> ) : ( diff --git a/src/services/Requests.tsx b/src/services/Requests.tsx index 8aec79b..071b159 100644 --- a/src/services/Requests.tsx +++ b/src/services/Requests.tsx @@ -4,7 +4,7 @@ import Constants from "expo-constants"; import { TCustomer, TCheckout, TUserKC, TReview, TUserReview } from "../../urubuy"; const iLocal = axios.create({ - baseURL: Constants.manifest?.extra?.URL_CLOUD, // ultra relativo cada pc tiene la suya localhost no funca :/ + baseURL: Constants.manifest?.extra?.URL_LOCAL, // ultra relativo cada pc tiene la suya localhost no funca :/ headers: { "Content-Type": "application/json" }, }); @@ -315,6 +315,12 @@ export const deleteCheckout = async (id: string) => { } }; +export const getPurchaseById = async (id: number) => { + if (id) { + return iLocal.get(`purchase/findById/${id}`); + } +}; + export const suspendAccount = async (email: string) => { if (email) { return iLocal.put(`user/suspend/${email}`); @@ -322,10 +328,17 @@ export const suspendAccount = async (email: string) => { }; export const reviewSeller = async (review: TUserReview) => { - console.log(review); return iLocal.post("userReview/add", review); }; +export const reviewProduct = async (review: any) => { + return iLocal.post("review/add", review); +}; + +export const toggleSettingNotifications = async (user: string) => { + if (user) return iLocal.put(`notifications/setting/${user}`); +}; + // operaciones para localstorage export const storeData = async (key: string, value: string) => { diff --git a/urubuy.d.ts b/urubuy.d.ts index 8d334b9..5c1ce53 100644 --- a/urubuy.d.ts +++ b/urubuy.d.ts @@ -24,6 +24,7 @@ export type TShoppingPost = { base64Images: string[]; sellerEmail: string; shoppingPostStatus: string; + reviews: TReview[]; }; export type minShoppingPost = { @@ -45,12 +46,6 @@ export type TUserKC = { password: string; }; -export type TAdministrator = { - username: string; - email: string; - password: string; -}; - export type TCustomer = { username: string; email: string; @@ -59,6 +54,7 @@ export type TCustomer = { addresses: string[]; averageRating: number; givenUserReviews?: TUserReview[]; + givenReviews?: TReview[]; receivedUserReviews?: TUserReview[]; purchases: TPurchase[]; }; @@ -129,6 +125,9 @@ export type TPurchase = { orderPayPalId: string; sellerEmail: string; customerEmail: string; + shoppingPosts: minShoppingPost[]; + customerReview: TUserReview; + sellerReview: TUserReview; }; export type TUserReview = { @@ -139,6 +138,7 @@ export type TUserReview = { customerEmail: string; sellerEmail: string; from: "CUSTOMER"; + purchaseId: number; }; export type TReview = { @@ -148,5 +148,5 @@ export type TReview = { base64Images: string[]; date: string; customerEmail: string; - sellerEmail: string; + shoppingPost: minShoppingPost; }; -- GitLab From 2883ad337d7cd12ce2671899ac0ddf6168efb2fd Mon Sep 17 00:00:00 2001 From: "mathias.fernandez.bo" <mathias.fernandez.bo@fing.edu.uy> Date: Thu, 8 Dec 2022 05:59:12 -0300 Subject: [PATCH 4/6] mejoras en android apk, y bugfixes everywhere --- .idea/.gitignore | 3 - .idea/frontmobile.iml | 14 ---- .idea/modules.xml | 8 --- .idea/vcs.xml | 6 -- src/App.tsx => App.tsx | 4 +- app.json | 15 ++-- assets/favicon.png | Bin 0 -> 6160 bytes eas.json | 6 +- src/components/CustomButton.tsx | 2 +- src/components/{ => Help}/FAQ.tsx | 32 ++++----- src/components/{ => Help}/PrivacyPolicy.tsx | 8 +-- src/components/Navigation/SideMenu.tsx | 20 ++++-- src/components/Navigation/Tabs.tsx | 5 +- src/components/SettingNotifications.tsx | 1 - src/screens/Help.tsx | 2 +- src/screens/Login.tsx | 8 ++- src/screens/ProductReviews.tsx | 8 ++- src/screens/{customer => }/Settings.tsx | 65 +++++++++++------ src/screens/ShoppingPost.tsx | 24 +++---- src/screens/UserProfile.tsx | 12 ++-- src/screens/customer/Addresses.tsx | 36 +++++----- src/screens/customer/Checkout.tsx | 2 +- src/screens/customer/GiveReview.tsx | 74 +++++++++++++------- src/screens/{ => customer}/Notification.tsx | 43 +++++++++--- src/screens/customer/Profile.tsx | 4 +- src/screens/customer/Purchase.tsx | 8 +-- src/screens/customer/Review.tsx | 18 ++--- src/services/Requests.tsx | 16 ++--- 28 files changed, 245 insertions(+), 199 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/frontmobile.iml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml rename src/App.tsx => App.tsx (70%) create mode 100644 assets/favicon.png rename src/components/{ => Help}/FAQ.tsx (63%) rename src/components/{ => Help}/PrivacyPolicy.tsx (96%) rename src/screens/{customer => }/Settings.tsx (89%) rename src/screens/{ => customer}/Notification.tsx (78%) diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 26d3352..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/.idea/frontmobile.iml b/.idea/frontmobile.iml deleted file mode 100644 index 697945a..0000000 --- a/.idea/frontmobile.iml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<module type="JAVA_MODULE" version="4"> - <component name="FacetManager"> - <facet type="android" name="Android"> - <configuration /> - </facet> - </component> - <component name="NewModuleRootManager" inherit-compiler-output="true"> - <exclude-output /> - <content url="file://$MODULE_DIR$" /> - <orderEntry type="jdk" jdkName="Android API 32 Platform" jdkType="Android SDK" /> - <orderEntry type="sourceFolder" forTests="false" /> - </component> -</module> \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 2c487de..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="ProjectModuleManager"> - <modules> - <module fileurl="file://$PROJECT_DIR$/.idea/frontmobile.iml" filepath="$PROJECT_DIR$/.idea/frontmobile.iml" /> - </modules> - </component> -</project> \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="VcsDirectoryMappings"> - <mapping directory="" vcs="Git" /> - </component> -</project> \ No newline at end of file diff --git a/src/App.tsx b/App.tsx similarity index 70% rename from src/App.tsx rename to App.tsx index 0f42b2c..aabf6be 100644 --- a/src/App.tsx +++ b/App.tsx @@ -1,7 +1,7 @@ import React from "react"; -import Navigation from "./Navigation"; +import Navigation from "./src/Navigation"; import { MenuProvider } from "react-native-popup-menu"; -import { getAdminToken } from "./services/Requests"; +import { getAdminToken } from "./src/services/Requests"; export default function App() { getAdminToken(); diff --git a/app.json b/app.json index a0fb3ea..f7a8638 100644 --- a/app.json +++ b/app.json @@ -8,7 +8,6 @@ "CLIENT_ID": "urubuy", "CLIENT_SECRET": "eiqRw4HaFHFzxADC8lz8xdiZ9LqJz4wj", "URL_LOCAL": "http://192.168.1.13:5000/", - "PAYPAL": "http://192.168.1.13:5000/paypal/pay/", "URL_CLOUD": "http://backend.uru-buy.me/", "URL_KC": "http://urubuy.ddns.net:8080/realms/Urubuy/protocol/openid-connect", "URL_KC_ADMIN": "http://urubuy.ddns.net:8080/admin/realms/Urubuy", @@ -28,9 +27,7 @@ "updates": { "fallbackToCacheTimeout": 0 }, - "assetBundlePatterns": [ - "**/*" - ], + "assetBundlePatterns": ["**/*"], "ios": { "supportsTablet": true, "bundleIdentifier": "com.fing.frontmobile", @@ -38,14 +35,10 @@ }, "android": { "adaptiveIcon": { - "foregroundImage": "./assets/adaptive-icon.png", - "backgroundColor": "#0c35c5", - "package": "com.fing.frontend.urubuy", - "versionCode": "1.0.0" + "foregroundImage": "./assets/favicon.png", + "backgroundColor": "#0c35c5" }, - "permissions": [ - "android.permission.RECORD_AUDIO" - ], + "permissions": ["android.permission.RECORD_AUDIO"], "package": "com.fing.frontmobile" }, "web": { diff --git a/assets/favicon.png b/assets/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..2966fe351a2e7544d107b282252b1ab48a469106 GIT binary patch literal 6160 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 literal 0 HcmV?d00001 diff --git a/eas.json b/eas.json index 7a6f4b0..3c86244 100644 --- a/eas.json +++ b/eas.json @@ -10,7 +10,11 @@ "preview": { "distribution": "internal" }, - "production": {} + "production": { + "android": { + "buildType": "apk" + } + } }, "submit": { "production": {} diff --git a/src/components/CustomButton.tsx b/src/components/CustomButton.tsx index b1891ba..27b00e3 100644 --- a/src/components/CustomButton.tsx +++ b/src/components/CustomButton.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { Text, TouchableOpacity, View } from "react-native"; +import { Text, TouchableOpacity } from "react-native"; export type Props = { onPress: any; diff --git a/src/components/FAQ.tsx b/src/components/Help/FAQ.tsx similarity index 63% rename from src/components/FAQ.tsx rename to src/components/Help/FAQ.tsx index 532f19d..ead9f6a 100644 --- a/src/components/FAQ.tsx +++ b/src/components/Help/FAQ.tsx @@ -1,38 +1,34 @@ -import { useColorScheme } from "nativewind"; -import { Copyright } from "phosphor-react-native"; import React from "react"; import { ScrollView, Text, View } from "react-native"; export default function FAQ() { - const { colorScheme } = useColorScheme(); - let dark = colorScheme === "dark"; return ( <> <View className="h-full w-full bg-[#fff] dark:bg-dark-mode-bg"> <ScrollView showsVerticalScrollIndicator={false}> <View className="flex flex-col items-center justify-center"> - <Text className="text-[#000] dark:text-[#fff] text-[20px] font-bold mt-5 underline"> FAQ </Text> <View className="flex flex-col items-center justify-center"> - <Text className="text-[#000] dark:text-[#fff] text-[22px] font-bold mt-5">¿Qué es la aplicación?</Text> + <Text className="text-[#000] dark:text-[#fff] text-[22px] font-bold mt-5">¿Qué es UruBuy?</Text> <Text className="text-[#000] dark:text-[#fff] text-[17px] font-bold p-2"> UruBuy es una plataforma de compra y venta de productos o popularmente conocida como una app de - e-commerce. Desde esta la aplicación podrás comprar productos de manera segura y confiable, teniendo la + e-commerce. Desde ésta aplicación podrás comprar productos de manera segura y confiable, teniendo la seguridad que brinda UruBuy, que verifica la identidad de cada vendedor a traves del sistema de identificación confirmada, que utiliza los datos reales de la cedula de identidad uruguaya, y utilizando - el método de pago más seguro y confiable de hoy en dia, PayPal. + el método de pago más seguro y confiable de hoy en dÃa, PayPal. Si te interesa vender productos, no + dudes en ingresar a http://uru-buy.me y registrarte como vendedor. </Text> <Text className="text-[#000] dark:text-[#fff] text-[22px] font-bold mt-5">¿Cómo comprar?</Text> <Text className="text-[#000] dark:text-[#fff] text-[17px] font-bold p-2"> - En primera instancia, deberas registrarte en la plataforma, a través del formulario de registro de esta + En primera instancia, deberás registrarte en la plataforma, a través del formulario de registro de esta aplicación, o desde la pagina principal http://uru-buy.me/ {"\n"} - Una vez registrado, deberás validar tu email para iniciar sesión en UruBuy. Si te gustó un producto, lo - puedes agregar al carrito desde la página del producto. Ten en cuenta que podrás agregar varios - productos al carrito, y elegir la dirección de retiro, o de delivery en caso de que el vendedor acepte - el mismo. Una vez que tengas todos los productos que deseas comprar en el carrito, deberás proceder a la - realizar el checkout, donde se te listará el detalle de tus productos con sus descuentos y costo de - delivery aplicados en caso que corresponda, y el total a pagar. Paypal ofrece los métodos de pagos - tradicionales de Visa y Mastercard para tarjetas de crédito o débito, como de otras tarjetas del - exterior, además de su ya conocida transferencia paypal entre cuentas. Si tu pago se procesa + Una vez registrado, deberás validar tu correo electrónico para iniciar sesión en UruBuy. Si te gustó un + producto, lo puedes agregar al carrito desde la página del producto, ten en cuenta que podrás agregar + varios productos al carrito, y elegir la dirección de retiro, o de delivery en caso de que el vendedor + acepte el mismo. Una vez que tengas todos los productos que deseas comprar en el carrito, deberás + proceder a la realizar el checkout, donde se te listará el detalle de tus productos con sus descuentos y + costo de delivery aplicados en caso que corresponda, y el total a pagar. Paypal ofrece los métodos de + pagos tradicionales de Visa y Mastercard para tarjetas de crédito o débito, como también otras tarjetas + del exterior, además de su ya conocida transferencia paypal entre cuentas. Si tu pago se procesa correcamente, un email con la factura de compra será enviada, y el vendedor recibirá tu orden para preparar. Nosotros te avisaremos cuando tu compra cambie de estado! </Text> @@ -43,7 +39,7 @@ export default function FAQ() { acceder a tus compras, y allà se te listaran las mismas. Elige la que desees calificar y tendrás la posibilidad de calificar al vendedor y a los productos de esa compra. Ten en cuenta que solamente podrás calificar una vez por compra, y que las calificaciones son visibles para todos los usuarios de la - plataforma. Tambien, puedes subir fotos a la reseña de productos. + plataforma. Además, puedes subir fotos a la reseña de productos. </Text> <Text className="text-[#000] dark:text-[#fff] text-[22px] font-bold mt-5">¿Tienes alguna duda?</Text> <Text className="text-[#000] dark:text-[#fff] text-[17px] font-bold p-2"> diff --git a/src/components/PrivacyPolicy.tsx b/src/components/Help/PrivacyPolicy.tsx similarity index 96% rename from src/components/PrivacyPolicy.tsx rename to src/components/Help/PrivacyPolicy.tsx index efec122..4d4b44d 100644 --- a/src/components/PrivacyPolicy.tsx +++ b/src/components/Help/PrivacyPolicy.tsx @@ -11,14 +11,14 @@ export default function PrivacyPolicy() { <View className="h-full w-full bg-[#fff] dark:bg-dark-mode-bg"> <ScrollView showsVerticalScrollIndicator={false}> <Text className="text-[18px] p-3 font-semibold text-[#000] flex-wrap max-w-screen-sm dark:text-dark-mode-text "> - 1. El sitio web https://uru-buy.me y las marcas relacionadas son propiedad de UruBuy. Hemos adoptado esta - PolÃtica de privacidad, que determina cómo procesamos la información recopilada por https://uru-buy.me, que + 1. El sitio web http://uru-buy.me y las marcas relacionadas son propiedad de UruBuy. Hemos adoptado esta + PolÃtica de privacidad, que determina cómo procesamos la información recopilada por http://uru-buy.me, que también proporciona las razones por las que debemos recopilar ciertos datos personales sobre ti. Por lo - tanto, debes leer esta PolÃtica de privacidad antes de usar el sitio web de https://uru-buy.me. + tanto, debes leer esta PolÃtica de privacidad antes de usar el sitio web de http://uru-buy.me. </Text> <Text className="text-[18px] p-3 font-semibold text-[#000] flex-wrap max-w-screen-sm dark:text-dark-mode-text "> 2. Cuidamos tus datos personales y nos comprometemos a garantizar su confidencialidad y seguridad. - Información personal que recopilamos: Cuando visitas https://uru-buy.me, recopilamos automáticamente cierta + Información personal que recopilamos: Cuando visitas http://uru-buy.me, recopilamos automáticamente cierta información sobre tu dispositivo, incluida información sobre tu navegador web, dirección IP, zona horaria y algunas de las cookies instaladas en tu dispositivo. Además, a medida que navegas, recopilamos información sobre las páginas web individuales o los productos que ves, qué sitios web o términos de búsqueda te diff --git a/src/components/Navigation/SideMenu.tsx b/src/components/Navigation/SideMenu.tsx index bfedccf..1ab5c8d 100644 --- a/src/components/Navigation/SideMenu.tsx +++ b/src/components/Navigation/SideMenu.tsx @@ -1,6 +1,6 @@ import React, { useState } from "react"; import { Alert, View, Text, TouchableOpacity, Platform } from "react-native"; -import Notification from "../../screens/Notification"; +import Notification from "../../screens/customer/Notification"; import ShoppingPost from "../../screens/ShoppingPost"; import _ShoppingCart from "../../screens/customer/ShoppingCart"; import Home from "../../screens/Home"; @@ -14,17 +14,29 @@ import { getData, getUserCart, removeData } from "../../services/Requests"; import { deleteUserCart } from "../../screens/customer/ShoppingCart"; import Purchase from "../../screens/customer/Purchase"; import Review from "../../screens/customer/Review"; -import { House, ShoppingCart, SignIn, At, User, SignOut, Info, ArrowLeft, Trash, Heart } from "phosphor-react-native"; +import { + House, + ShoppingCart, + SignIn, + At, + User, + SignOut, + Info, + ArrowLeft, + Trash, + Heart, + PlusCircle, +} from "phosphor-react-native"; import UserProfile from "../../screens/UserProfile"; import { useColorScheme } from "nativewind"; -import PrivacyPolicy from "../PrivacyPolicy"; +import PrivacyPolicy from "../Help/PrivacyPolicy"; import Likes from "../../screens/customer/Likes"; import GiveReview from "../../screens/customer/GiveReview"; import CheckoutScreen from "../../screens/customer/Checkout"; import Addresses from "../../screens/customer/Addresses"; import SellerReview from "../../screens/SellerReviews"; import ProductReviews from "../../screens/ProductReviews"; -import FAQ from "../FAQ"; +import FAQ from "../Help/FAQ"; const Drawer = createDrawerNavigator(); diff --git a/src/components/Navigation/Tabs.tsx b/src/components/Navigation/Tabs.tsx index 594e4c2..e7d1ba5 100644 --- a/src/components/Navigation/Tabs.tsx +++ b/src/components/Navigation/Tabs.tsx @@ -2,7 +2,7 @@ import React from "react"; import { createBottomTabNavigator } from "@react-navigation/bottom-tabs"; import { createNativeStackNavigator } from "@react-navigation/native-stack"; import SideMenu from "./SideMenu"; -import SettingsScreen from "../../screens/customer/Settings"; +import SettingsScreen from "../../screens/Settings"; import { Gear, House } from "phosphor-react-native"; import { useColorScheme } from "nativewind"; import { useNavigation } from "@react-navigation/core"; @@ -25,13 +25,12 @@ function _SideMenu(props: any) { ); } -export default function MyTab() { +export default function BottomTabs() { const { colorScheme } = useColorScheme(); let dark = colorScheme === "dark"; const nav = useNavigation(); return ( <Tab.Navigator initialRouteName="Home" screenOptions={{ tabBarActiveTintColor: "#0c35c5" }}> - {/* pestañas inferiores */} <Tab.Screen name="Home" component={_SideMenu} diff --git a/src/components/SettingNotifications.tsx b/src/components/SettingNotifications.tsx index 4d4d445..bf2ecf5 100644 --- a/src/components/SettingNotifications.tsx +++ b/src/components/SettingNotifications.tsx @@ -61,7 +61,6 @@ export default function SettingNotifications() { responseListener.current = Notifications.addNotificationResponseReceivedListener(() => { // if (notificationData.category === 'promociones') { // filter by category of notifications let k = notificationData.category; - console.log("k es: ", k); k === "estado" ? nav.navigate( "Notification" as never, diff --git a/src/screens/Help.tsx b/src/screens/Help.tsx index f281c1b..f3e78ed 100644 --- a/src/screens/Help.tsx +++ b/src/screens/Help.tsx @@ -83,7 +83,7 @@ function Help() { </TouchableOpacity> <Text className="font-bold text-header-color dark:text-gold-buy">UruBuy @ 2022</Text> <Text className="p-2 mt-3 font-medium dark:text-dark-mode-text"> - Somos un grupo de desarrolladores de Uruguay, estudiantes de Tecnólogo en informática. Esta aplicación + Somos un grupo de desarrolladores de Uruguay, estudiantes de Tecnólogo en informática. Ésta aplicación fue desarrollada como proyecto final de la carrera. </Text> </View> diff --git a/src/screens/Login.tsx b/src/screens/Login.tsx index 8d8bc54..c14801d 100644 --- a/src/screens/Login.tsx +++ b/src/screens/Login.tsx @@ -171,7 +171,13 @@ export default function Login() { /> <View className="flex-row items-center justify-center"> <CustomButton isDisabled={false} onPress={handleLogin} value="Ingresar" style={{}} /> - <View className="absolute right-[285px] top-[27px]"> + <View + className={ + Platform.OS === "android" + ? "absolute right-[275px] top-[30px]" + : "absolute right-[285px] top-[27px]" + } + > <SignIn size={22} weight="fill" color="white" /> </View> </View> diff --git a/src/screens/ProductReviews.tsx b/src/screens/ProductReviews.tsx index 0a68c7d..6ae07cd 100644 --- a/src/screens/ProductReviews.tsx +++ b/src/screens/ProductReviews.tsx @@ -95,9 +95,11 @@ export default function ProductReview(props: any) { {review.description} </Text> </View> - <View className="p-2 scale-50 -mb-28 -mt-28"> - <SliderSlick pictures={review.base64Images} /> - </View> + {review.base64Images ? ( + <View className="p-2 scale-50 -mb-28 -mt-28"> + <SliderSlick pictures={review.base64Images} /> + </View> + ) : null} </View> ); }; diff --git a/src/screens/customer/Settings.tsx b/src/screens/Settings.tsx similarity index 89% rename from src/screens/customer/Settings.tsx rename to src/screens/Settings.tsx index 9997904..36de2d1 100644 --- a/src/screens/customer/Settings.tsx +++ b/src/screens/Settings.tsx @@ -30,19 +30,13 @@ import { } from "phosphor-react-native"; import { Appearance } from "react-native"; import { useColorScheme } from "nativewind"; -import CustomReport, { ReportIOS } from "../../components/Report/CustomReport"; -import CustomInput from "../../components/CustomInput"; -import { - getCustomerProfile, - getData, - login, - suspendAccount, - toggleSettingNotifications, -} from "../../services/Requests"; +import CustomReport, { ReportIOS } from "../components/Report/CustomReport"; +import CustomInput from "../components/CustomInput"; +import { getCustomerProfile, getData, login, suspendAccount, toggleSettingNotifications } from "../services/Requests"; import { useFocusEffect, useNavigation } from "@react-navigation/core"; -import { removeDataStored } from "./Logout"; -import { TUserKC } from "../../../urubuy"; -import Loading from "../../components/Loading"; +import { removeDataStored } from "./customer/Logout"; +import { TUserKC } from "../../urubuy"; +import Loading from "../components/Loading"; function Settings() { const version: string = "1.0"; @@ -71,6 +65,7 @@ function Settings() { useEffect(() => { const unsubscribe = nav.addListener("blur", () => { setUserPassword(""); + setPromptAndroid(false); }); return unsubscribe; }, []); @@ -169,13 +164,13 @@ function Settings() { setNtfEnabled(r); } }) - .catch((e) => console.log(e)); + .catch((e) => console.log(e.response.data)); }; return ( <> <ImageBackground - source={require("../../../assets/abstract.jpg")} + source={require("../../assets/abstract.jpg")} resizeMode="cover" className="w-full h-full bg-no-repeat" blurRadius={6} @@ -184,7 +179,15 @@ function Settings() { {!loading ? ( <> - <Text className="mt-8 mr-7 p-2 text-[45px] font-extrabold text-[#fff]">Configuración</Text> + <Text + className={ + Platform.OS === "android" + ? "text-[35px] " + "mt-3 mr-7 p-2 font-extrabold text-[#fff]" + : "text-[42px] " + "mt-5 mr-7 p-2 font-extrabold text-[#fff]" + } + > + Configuración + </Text> <Divider style={{ height: 1.3, backgroundColor: "white" }} /> <ScrollView showsVerticalScrollIndicator={false}> <Text className="text-[#fff] text-[18px] font-bold mt-[20px] ml-3 p-2">Opciones generales </Text> @@ -379,7 +382,13 @@ function Settings() { > <XCircle size={25} weight="regular" color={colorScheme === "dark" ? "white" : "black"} /> </TouchableOpacity> - <Text className="text-[#f00] text-[19px] font-semibold mx-auto"> + <Text + className={ + Platform.OS === "android" + ? "text-[17px] " + "text-[#f00] font-semibold mx-auto" + : "text-[19px] " + "text-[#f00] font-semibold mx-auto" + } + > Estás apunto de suspender tu cuenta </Text> <Text className="text-[#000] dark:text-dark-mode-text text-[18px] font-semibold mx-auto mt-2"> @@ -398,7 +407,11 @@ function Settings() { <X weight="fill" size={19} - style={{ padding: 2, marginTop: 12, marginRight: 5 }} + style={ + Platform.OS === "android" + ? { padding: 2, marginTop: 16.5, marginRight: 5 } + : { padding: 2, marginTop: 12, marginRight: 5 } + } color={"green"} /> </TouchableOpacity> @@ -412,7 +425,11 @@ function Settings() { <ArrowFatLinesRight weight="duotone" size={19} - style={{ padding: 2, marginTop: 12, marginRight: 5 }} + style={ + Platform.OS === "android" + ? { padding: 2, marginTop: 16.5, marginRight: 5 } + : { padding: 2, marginTop: 12, marginRight: 5 } + } color={"red"} /> </TouchableOpacity> @@ -482,7 +499,11 @@ function Settings() { <X weight="fill" size={19} - style={{ padding: 2, marginTop: 12, marginRight: 5 }} + style={ + Platform.OS === "android" + ? { padding: 2, marginTop: 16.5, marginRight: 5 } + : { padding: 2, marginTop: 12, marginRight: 5 } + } color={"green"} /> </TouchableOpacity> @@ -496,7 +517,11 @@ function Settings() { <Check weight="fill" size={19} - style={{ padding: 2, marginTop: 12, marginRight: 5 }} + style={ + Platform.OS === "android" + ? { padding: 2, marginTop: 16.5, marginRight: 5 } + : { padding: 2, marginTop: 12, marginRight: 5 } + } color={"red"} /> </TouchableOpacity> diff --git a/src/screens/ShoppingPost.tsx b/src/screens/ShoppingPost.tsx index dd19ca8..c408d3f 100644 --- a/src/screens/ShoppingPost.tsx +++ b/src/screens/ShoppingPost.tsx @@ -199,7 +199,6 @@ export default function ShoppingPost(props: any) { <TouchableOpacity className={Platform.OS === "android" ? "ml-5" : ""} onPress={() => { - console.log(shoppingPost.reviews.length); nav.navigate("ProductReviews" as never, { reviews: shoppingPost.reviews } as never); }} > @@ -211,26 +210,21 @@ export default function ShoppingPost(props: any) { starSize={23} /> <Text className="font-semibold mt-1 ml-2 text-[17px] text-dark-mode-text"> - {Math.floor(Math.random() * Math.max(shoppingPost?.averageRating!, 10))} + {shoppingPost.reviews.length} </Text> </View> </TouchableOpacity> </View> {activeUser ? ( - <> + <View className="p-1 m-1"> <CustomButton isDisabled={false} onPress={() => handleAddCart()} value="Agregar al carrito" style={{}} /> - <View - className={Platform.select({ - ios: "absolute bottom-[9.5px] left-[21%]", - android: "absolute bottom-[9.5px] left-[21%]", - })} - > + <View className="absolute bottom-[14px] left-[21%]"> <ShoppingCartSimple size={19} weight="duotone" color="white" /> </View> {false && ( @@ -241,9 +235,9 @@ export default function ShoppingPost(props: any) { style={{ backgroundColor: "red" }} /> )} - </> + </View> ) : ( - <> + <View className="p-1 m-1"> <CustomButton isDisabled={false} onPress={() => handleLogin()} @@ -252,19 +246,19 @@ export default function ShoppingPost(props: any) { /> <View className={Platform.select({ - ios: "absolute bottom-[9.5px] left-[21%]", - android: "absolute bottom-[9.5px] left-[21%]", + ios: "absolute bbottom-[14px] left-[21%]", + android: "absolute bottom-[14px] left-[21%]", })} > <ShoppingCartSimple size={19} weight="duotone" color="white" /> </View> - </> + </View> )} </ScrollView> ) : ( <View className="flex mx-auto my-auto"> <Text className="text-center text-[20px] font-bold text-dark-mode-text"> - Ha ocurrido un problema, lo sentimos + Ha ocurrido un problema, lo sentimos. </Text> </View> )} diff --git a/src/screens/UserProfile.tsx b/src/screens/UserProfile.tsx index a37a0f1..33f43eb 100644 --- a/src/screens/UserProfile.tsx +++ b/src/screens/UserProfile.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useState } from "react"; -import { Text, View, Image, Alert, FlatList } from "react-native"; +import { Text, View, Image, Alert, FlatList, Platform } from "react-native"; import { getCustomerProfile, getSellerProfile } from "../services/Requests"; import { useNavigation } from "@react-navigation/core"; import Loading from "../components/Loading"; @@ -78,7 +78,9 @@ function UserProfile(props: any) { {user?.picture !== undefined && user?.picture !== "" && user?.picture !== null ? ( <Image source={ - user?.picture.includes("data:image") + user.picture.includes("http") + ? { uri: user.picture } + : user.picture.includes("data:image") ? { uri: user?.picture } : { uri: `data:image/jpg;base64,${user?.picture}` } } @@ -123,7 +125,9 @@ function UserProfile(props: any) { {user?.picture !== undefined && user?.picture !== "" && user?.picture !== null ? ( <Image source={ - user?.picture.includes("data:image") + user.picture.includes("http") + ? { uri: user.picture } + : user.picture.includes("data:image") ? { uri: user?.picture } : { uri: `data:image/jpg;base64,${user?.picture}` } } @@ -155,7 +159,7 @@ function UserProfile(props: any) { style={undefined} isDisabled={false} /> - <View className="left-[72px] bottom-7"> + <View className={Platform.OS === "android" ? "left-[40px] bottom-[12px]" : "left-[72px] bottom-7"}> <Star size={20} color="white" weight="duotone" /> </View> </> diff --git a/src/screens/customer/Addresses.tsx b/src/screens/customer/Addresses.tsx index f3db3ef..e36f3fa 100644 --- a/src/screens/customer/Addresses.tsx +++ b/src/screens/customer/Addresses.tsx @@ -4,11 +4,9 @@ import { FlatList, ImageBackground, Image, Text, View, Platform, Alert, Modal } import { Divider, TextInput } from "react-native-paper"; import { useColorScheme } from "nativewind"; import { Check, HouseSimple, Pencil, Star, X, XCircle } from "phosphor-react-native"; -import CustomButton from "../../components/CustomButton"; -import { TSeller } from "../../../urubuy"; -import { getCustomerProfile } from "../../services/Requests"; import { TouchableOpacity } from "react-native-gesture-handler"; import CustomInput from "../../components/CustomInput"; +import { deleteAddressCustomer } from "../../services/Requests"; export default function Addresses(props: any) { const nav = useNavigation(); @@ -17,9 +15,11 @@ export default function Addresses(props: any) { const dark = colorScheme === "dark"; const [showEditAddress, setShowEditAddress] = useState(false); const [newAddress, setNewAddress] = useState(""); + const [user, setUser] = useState(""); useEffect(() => { setAddresses(props.route.params.addresses); + setUser(props.route.params.user); }, [props]); const deleteAddress = (addr: string) => { @@ -32,8 +32,12 @@ export default function Addresses(props: any) { text: "Eliminar", style: "destructive", onPress: () => { - Alert.alert("Direccion borrada"); - // actualizar state + deleteAddressCustomer(user, addr) + .then((r: any) => (r.status === 200 ? setAddresses(r.data) : Alert.alert("Error al borrar la dirección"))) + .catch((e) => { + console.log(e); + Alert.alert("Error al borrar la dirección"); + }); }, }, ]); @@ -44,7 +48,7 @@ export default function Addresses(props: any) { address: string; }; - const Card: React.FC<TAddrress> = ({ index, address }) => { + const Card: React.FC<TAddrress> = ({ address }) => { return ( <View className=" @@ -55,25 +59,17 @@ export default function Addresses(props: any) { dark:bg-dark-mode-bg border-header-color rounded-md border-[1.13px]" > - <View className="flex-row justify-between inline-block align-middle "> - <Text className="text-[18px] p-[11px] dark:text-dark-mode-text font-semibold">{index}</Text> - <View className="flex-row justify-end right-5 p-[11px]"> - <TouchableOpacity onPress={() => setShowEditAddress(true)}> + <View className="flex-row justify-between"> + <Text className="text-[18px] p-[11px] dark:text-dark-mode-text font-semibold">{address}</Text> + <View className="flex-row justify-end p-[11px]"> + {/*<TouchableOpacity onPress={() => setShowEditAddress(true)}> <Pencil size={24} weight="bold" color={dark ? "white" : "black"} /> - </TouchableOpacity> + </TouchableOpacity>*/} <TouchableOpacity onPress={() => deleteAddress(address)}> - <X - size={24} - weight="bold" - color={"red"} - style={Platform.OS === "android" ? { marginLeft: 15 } : { marginRight: -15, marginLeft: 15 }} - /> + <X size={24} weight="bold" color={"red"} style={{ marginLeft: 15 }} /> </TouchableOpacity> </View> </View> - <View className="flex-row align-middle"> - <Text className="text-[18px] p-[11px] dark:text-dark-mode-text font-semibold">{address}</Text> - </View> </View> ); }; diff --git a/src/screens/customer/Checkout.tsx b/src/screens/customer/Checkout.tsx index 31243c0..9e6084e 100644 --- a/src/screens/customer/Checkout.tsx +++ b/src/screens/customer/Checkout.tsx @@ -18,7 +18,7 @@ export default function Checkout(props: any) { const nav = useNavigation(); const [errorMessage, setErrorMessage] = useState(""); const [successMessage, setSuccessMessage] = useState(""); - const urlPay = Constants.manifest?.extra?.URL_LOCAL + "paypal/pay/"; + const urlPay = Constants.manifest?.extra?.URL_CLOUD + "paypal/pay/"; const [shoppingCartId, setShoppingCartId] = useState<string | undefined>(""); const [checkout, setCheckout] = useState<TCheckoutResponse | undefined>(undefined); const [loadingRedirect, setLoadingRedirect] = useState(false); diff --git a/src/screens/customer/GiveReview.tsx b/src/screens/customer/GiveReview.tsx index 155cd3f..9f0eb8f 100644 --- a/src/screens/customer/GiveReview.tsx +++ b/src/screens/customer/GiveReview.tsx @@ -26,7 +26,7 @@ export default function GiveReview(props: any) { const [reviewComment, setReviewComment] = useState(""); const [images, setImages] = useState<string[] | undefined>([]); const [photos, setPhotos] = useState<GReview[] | undefined>([]); - const [defaultRating, setDefaultRating] = useState(2); + const [defaultRating, setDefaultRating] = useState(3); const { colorScheme } = useColorScheme(); const dark = colorScheme === "dark"; const [inputHeight, setInputHeight] = useState(0); @@ -182,8 +182,8 @@ export default function GiveReview(props: any) { {purchase && purchase.shoppingPosts && purchase.shoppingPosts.length > 0 && - purchase.shoppingPosts.map((p) => ( - <View className="flex-row flex-wrap"> + purchase.shoppingPosts.map((p, i) => ( + <View key={i} className="flex-row flex-wrap"> <TouchableOpacity onPress={() => handleProduct(p)}> <Text className="p-1 text-lg font-semibold text-gold-buy">{"‣ " + p.title}</Text> </TouchableOpacity> @@ -199,7 +199,7 @@ export default function GiveReview(props: any) { style={undefined} isDisabled={false} /> - <View className="left-[57px] bottom-7"> + <View className={Platform.OS === "android" ? "left-[54px] bottom-[31px]" : "left-[57px] bottom-7"}> <UserCircle size={19} color={"white"} weight="duotone" /> </View> </> @@ -275,24 +275,44 @@ export default function GiveReview(props: any) { style={dark ? { height: 2, backgroundColor: "white" } : { height: 2, backgroundColor: "#32377B" }} /> <View className="w-[300]"> - <TextInput - placeholder="Comentario" - multiline={true} - left={ - <TextInput.Icon - name={() => <ChatCircleDots size={18} weight="bold" color={dark ? "white" : "black"} />} - /> - } - onChangeText={setReviewComment} - onContentSizeChange={(e) => setInputHeight(e.nativeEvent.contentSize.height)} - theme={dark ? { colors: { placeholder: "white", text: "white" } } : {}} - style={ - dark - ? [myStyle.textAreaB, { height: Math.max(50, inputHeight) }] - : [myStyle.textArea, { height: Math.max(50, inputHeight) }] - } - value={reviewComment} - /> + {Platform.OS === "ios" ? ( + <TextInput + placeholder="Comentario" + multiline={true} + left={ + <TextInput.Icon + name={() => <ChatCircleDots size={18} weight="bold" color={dark ? "white" : "black"} />} + /> + } + onChangeText={setReviewComment} + onContentSizeChange={(e) => setInputHeight(e.nativeEvent.contentSize.height)} + theme={dark ? { colors: { placeholder: "white", text: "white" } } : {}} + style={ + dark + ? [myStyle.textAreaB, { height: Math.max(50, inputHeight) }] + : [myStyle.textArea, { height: Math.max(50, inputHeight) }] + } + value={reviewComment} + /> + ) : ( + <TextInput + placeholder="Comentario" + multiline={true} + left={ + <TextInput.Icon + name={() => <ChatCircleDots size={18} weight="bold" color={dark ? "white" : "black"} />} + /> + } + onChangeText={setReviewComment} + theme={dark ? { colors: { placeholder: "white", text: "white" } } : {}} + style={ + dark + ? [myStyle.textAreaB, { height: Math.max(50, inputHeight) }] + : [myStyle.textArea, { height: Math.max(50, inputHeight) }] + } + value={reviewComment} + /> + )} </View> <View className="flex-row mt-2 text-start"> <Text className="mt-3 text-lg font-semibold dark:text-dark-mode-text">Calificación: </Text> @@ -316,7 +336,11 @@ export default function GiveReview(props: any) { style={undefined} isDisabled={false} /> - <View className={"right-8 top-[26]"}> + <View + className={ + Platform.OS === "android" ? "right-[179px] top-[27px]" : "right-[180px] top-[25px]" + } + > <ImageSquare size={20} weight="fill" color={"white"} /> </View> </View> @@ -350,7 +374,9 @@ export default function GiveReview(props: any) { style={{ width: 130, margin: 10 }} isDisabled={false} /> - <View className={"right-[132px] top-[25px]"}> + <View + className={Platform.OS === "android" ? "right-[135px] top-[27px]" : "right-[132px] top-[25px]"} + > <X size={20} weight="fill" color="white" /> </View> <CustomButton diff --git a/src/screens/Notification.tsx b/src/screens/customer/Notification.tsx similarity index 78% rename from src/screens/Notification.tsx rename to src/screens/customer/Notification.tsx index ee66528..5e5ae7d 100644 --- a/src/screens/Notification.tsx +++ b/src/screens/customer/Notification.tsx @@ -1,13 +1,13 @@ import React, { useEffect, useState } from "react"; import { FlatList, ImageBackground, Text, TouchableOpacity, View } from "react-native"; import { Card } from "@rneui/themed"; -import { TPurchase, TShoppingPost } from "../../urubuy"; -import { getPurchaseById, getShoppingPosts } from "../services/Requests"; +import { TPurchase, TShoppingPost } from "../../../urubuy"; +import { getPurchaseById, getShoppingPosts } from "../../services/Requests"; import { useColorScheme } from "nativewind"; import { useNavigation } from "@react-navigation/core"; -import Loading from "../components/Loading"; +import Loading from "../../components/Loading"; import { Truck } from "phosphor-react-native"; -import { handleStatus } from "./customer/Purchase"; +import { handleStatus } from "./Purchase"; const noitem = require("../../assets/noitem.png"); type ScrollList = { @@ -195,14 +195,37 @@ export default function Notification(props: any) { blurRadius={6} > {status && purchase && categoryNotification === "estado" ? ( - <View className="w-auto mx-auto my-auto border-[1.33px] border-header-color rounded-3xl h-auto"> - <Text className="text-[22px] p-4 font-bold dark:text-dark-mode-text"> + <View className="w-auto mx-auto my-auto border-[1.33px] m-2 border-header-color bg-[#fff] dark:bg-dark-mode-bg rounded-3xl h-auto"> + <Text className="text-[22px] p-4 font-bold text-[#000] dark:text-dark-mode-text"> Estado de la compra: {purchase.orderPayPalId} </Text> - <Text className="text-[17px] p-3 font-bold dark:text-dark-mode-text"> - Estado: {handleStatus(purchase?.status)} - </Text> - <Text className="text-[17px] p-3 font-bold dark:text-dark-mode-text">Fecha: {purchase?.date}</Text> + <View className="flex flex-row flex-wrap"> + <Text className="text-[17px] p-2 font-bold text-[#000] dark:text-dark-mode-text"> + Compra: {purchase?.date} + </Text> + <Text className="text-[17px] p-2 font-bold text-[#000] dark:text-dark-mode-text"> + Estado: {handleStatus(purchase?.status)} + </Text> + </View> + <Text className="text-[17px] p-3 font-bold text-[#000] dark:text-dark-mode-text">Items</Text> + <View className="flex flex-col"> + {purchase?.shoppingPosts.map((item, index) => ( + <View key={index} className="flex flex-row flex-wrap justify-between"> + <Text className="text-[17px] p-3 font-bold text-[#000] dark:text-dark-mode-text"> + {"‣ " + item.title} + </Text> + </View> + ))} + </View> + {purchase?.status === "DELIVERED" && ( + <View className="w-auto mx-auto my-auto border-[1.33px] m-2 border-header-color bg-[#fff] dark:bg-dark-mode-bg rounded-3xl h-auto"> + <Text className="text-[17px] p-4 font-semibold text-[#000] dark:text-dark-mode-text"> + Tu opinion es importante! No te olvides de calificar al vendedor y a los productos comprados, nos + ayudará a mejorar. {"\n"} + ¡Que disfrutes de tu compra! + </Text> + </View> + )} </View> ) : !loading ? ( <FlatList diff --git a/src/screens/customer/Profile.tsx b/src/screens/customer/Profile.tsx index f7991a9..07c7e87 100644 --- a/src/screens/customer/Profile.tsx +++ b/src/screens/customer/Profile.tsx @@ -72,6 +72,7 @@ function Profile() { }) .catch((err) => { console.error(err); + Alert.alert("Ocurrio un problema al eliminar la foto de perfil"); }); }, }, @@ -109,7 +110,7 @@ function Profile() { setLoading(false); } else { setLoading(false); - Alert.alert("Imposible enviar mail"); + Alert.alert("Ha ocurrido un error al enviar mail"); } }) .catch((er) => { @@ -244,6 +245,7 @@ function Profile() { "Addresses" as never, { addresses: user?.addresses, + user: user?.email, } as never, ) } diff --git a/src/screens/customer/Purchase.tsx b/src/screens/customer/Purchase.tsx index 32f0a9e..930357a 100644 --- a/src/screens/customer/Purchase.tsx +++ b/src/screens/customer/Purchase.tsx @@ -91,7 +91,7 @@ export default function Purchase(props: any) { </Text> </View> <Divider style={dark ? { height: 1.5, backgroundColor: "white" } : { height: 1.5 }} /> - <View className="flex-row justify-between"> + <View className="flex-row flex-wrap justify-between"> <View className="flex-row"> <Text className="text-[18px] p-[11px] dark:text-dark-mode-text font-semibold">Vendedor:</Text> <TouchableOpacity @@ -100,9 +100,7 @@ export default function Purchase(props: any) { <Text className="text-[18px] p-[11px] text-gold-buy font-semibold">{purchase.sellerEmail}</Text> </TouchableOpacity> </View> - <Text className="text-[18px] p-[11px] mb-[-5px] dark:text-dark-mode-text font-semibold"> - USD {purchase.total} - </Text> + <Text className="text-[18px] p-[11px] dark:text-dark-mode-text font-semibold">USD {purchase.total}</Text> </View> {purchase.shoppingPosts.map((x, i) => ( <Text key={i} className="text-[18px] p-[11px] text-right dark:text-dark-mode-text font-semibold"> @@ -120,7 +118,7 @@ export default function Purchase(props: any) { <View className={Platform.select({ ios: "absolute left-[116px] mt-[25px]", - android: "absolute left-[109px] mt-[24px]", + android: "absolute left-[111px] mt-[30px]", })} > <Star size={21} color="white" /> diff --git a/src/screens/customer/Review.tsx b/src/screens/customer/Review.tsx index 916b669..ef144c4 100644 --- a/src/screens/customer/Review.tsx +++ b/src/screens/customer/Review.tsx @@ -1,6 +1,6 @@ import { useNavigation } from "@react-navigation/core"; import React, { useEffect, useState } from "react"; -import { FlatList, ImageBackground, Text, View, TouchableOpacity, useWindowDimensions } from "react-native"; +import { FlatList, ImageBackground, Text, View, TouchableOpacity, useWindowDimensions, Platform } from "react-native"; import { Divider } from "react-native-paper"; import { useColorScheme } from "nativewind"; import { TUserReview, TReview } from "../../../urubuy"; @@ -32,6 +32,12 @@ export default function Review(props: any) { { key: "givenReviews", title: "Reseñas a productos" }, ]); + useEffect(() => { + setGivenReviewsUser(props.route.params.givenUserReviews); + setRecievedReviewsUser(props.route.params.receivedUserReviews); + setGivenReviews(props.route.params.givenReviews); + }, [props]); + const _receivedUserReview = () => ( <ImageBackground source={require("../../../assets/abstract.jpg")} @@ -131,12 +137,6 @@ export default function Review(props: any) { givenReviews: _givenReviews, }); - useEffect(() => { - setGivenReviewsUser(props.route.params.givenUserReviews); - setRecievedReviewsUser(props.route.params.receivedUserReviews); - setGivenReviews(props.route.params.givenReviews); - }, [props]); - const handleProfileSeller = (seller: string) => { nav.navigate( "UserProfile" as never, @@ -260,7 +260,9 @@ export default function Review(props: any) { activeColor="#0c35c5" inactiveColor="#501728" indicatorStyle={{ backgroundColor: "#0c35c5" }} - labelStyle={{ fontSize: 16, fontWeight: "bold" }} + labelStyle={ + Platform.OS === "android" ? { fontWeight: "bold", fontSize: 14 } : { fontSize: 16, fontWeight: "bold" } + } style={{ backgroundColor: "white" }} /> )} diff --git a/src/services/Requests.tsx b/src/services/Requests.tsx index 071b159..83d142b 100644 --- a/src/services/Requests.tsx +++ b/src/services/Requests.tsx @@ -4,17 +4,10 @@ import Constants from "expo-constants"; import { TCustomer, TCheckout, TUserKC, TReview, TUserReview } from "../../urubuy"; const iLocal = axios.create({ - baseURL: Constants.manifest?.extra?.URL_LOCAL, // ultra relativo cada pc tiene la suya localhost no funca :/ - headers: { "Content-Type": "application/json" }, -}); - -// axios cloud -const iAWS = axios.create({ baseURL: Constants.manifest?.extra?.URL_CLOUD, headers: { "Content-Type": "application/json" }, }); -// axios auth const iAuth = axios.create({ baseURL: Constants.manifest?.extra?.URL_KC }); const iAdmin_KC = axios.create({ baseURL: Constants.manifest?.extra?.URL_KC_ADMIN }); @@ -72,12 +65,9 @@ export const getAdminToken = async () => { password: "urubuy", }); - // const hayToken = await getData("tokenAdmin"); - // if (hayToken === undefined) { const res = await iAuth.post("/token", params.toString(), header); console.log("pido tokenAdmin"); await storeData("tokenAdmin", res.data.access_token); - // } else console.log("ya hay token"); }; export const login = (user: TUserKC) => { @@ -293,6 +283,12 @@ export const addNewCustomerAddress = async (address: string) => { } }; +export const deleteAddressCustomer = async (_email: string, address: string) => { + if (_email && address) { + return iLocal.delete(`user/deleteAddressCustomer/${_email}/${address}`); + } +}; + export const addCustomerCheckout = async (checkout: TCheckout[], email: string) => { if (email) { let newCheckout = { -- GitLab From 078adc066c803f2f1101a6b092105e30b281bb84 Mon Sep 17 00:00:00 2001 From: "mathias.fernandez.bo" <mathias.fernandez.bo@fing.edu.uy> Date: Fri, 9 Dec 2022 03:44:26 -0300 Subject: [PATCH 5/6] fix notifications, intento de suspended view --- src/components/SettingNotifications.tsx | 41 ++++++++++++------------- src/screens/ProductReviews.tsx | 29 +++-------------- src/screens/SellerReviews.tsx | 7 +++-- src/screens/UserProfile.tsx | 1 + src/screens/customer/Notification.tsx | 18 +++++------ src/services/Requests.tsx | 4 +++ urubuy.d.ts | 2 ++ 7 files changed, 42 insertions(+), 60 deletions(-) diff --git a/src/components/SettingNotifications.tsx b/src/components/SettingNotifications.tsx index bf2ecf5..8beb39e 100644 --- a/src/components/SettingNotifications.tsx +++ b/src/components/SettingNotifications.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useRef, useState } from "react"; import { useNavigation } from "@react-navigation/core"; import * as Notifications from "expo-notifications"; import * as Device from "expo-device"; -import { getData, sendToken } from "../services/Requests"; +import { sendToken } from "../services/Requests"; import { Platform } from "react-native"; Notifications.setNotificationHandler({ @@ -39,15 +39,11 @@ export default function SettingNotifications() { registerForPushNotificationsAsync().then(async (token) => { setExpoPushToken(token!); manageSentToken(token); - getData("userNotification").then((res) => { - // al pedo pq la notificacion llega al server de expo, hay q controlarlo del backend - if (res && res === "false") setUserNotification(false); - else if (res && res === "true") setUserNotification(true); - }); }); - + let k: any; // This listener is fired whenever a notification is received while the app is foregrounded notificationListener.current = Notifications.addNotificationReceivedListener((notification: any) => { + k = notification.request.content.data.category; setNotification(notification); setData({ title: notification.request.content.title, @@ -60,21 +56,22 @@ export default function SettingNotifications() { // This listener when is tapped responseListener.current = Notifications.addNotificationResponseReceivedListener(() => { // if (notificationData.category === 'promociones') { // filter by category of notifications - let k = notificationData.category; - k === "estado" - ? nav.navigate( - "Notification" as never, - { - category: k, - purchaseId: notificationData.purchaseId, - } as never, - ) - : nav.navigate( - "Notification" as never, - { - category: `${k}`, - } as never, - ); + k !== "" + ? k === "estado" + ? nav.navigate( + "Notification" as never, + { + category: k, + purchaseId: notificationData.purchaseId, + } as never, + ) + : nav.navigate( + "Notification" as never, + { + category: k, + } as never, + ) + : console.log("no category"); }) as never; }, [notificationData, nav]); diff --git a/src/screens/ProductReviews.tsx b/src/screens/ProductReviews.tsx index 6ae07cd..a4b5c5c 100644 --- a/src/screens/ProductReviews.tsx +++ b/src/screens/ProductReviews.tsx @@ -11,47 +11,23 @@ import SliderSlick from "../components/SliderSlick"; type ReviewCard = { review: TReview; }; - -type TReviewUsername = { - username: string; - reviewId: number; -}; - export default function ProductReview(props: any) { const [receivedReviews, setRecievedReviews] = useState<TReview[] | undefined>([]); - const [reviewUsername, setReviewUsername] = useState<TReviewUsername[] | undefined>([]); const { colorScheme } = useColorScheme(); const dark = colorScheme === "dark"; const nav = useNavigation(); useFocusEffect(() => { setRecievedReviews(props.route.params.reviews); - // handleCustomer(props.route.params.reviews); }); useEffect(() => { const unsuscribe = nav.addListener("blur", () => { setRecievedReviews([]); - setReviewUsername([]); }); return unsuscribe; }, []); - // not working customer username by review idk why repite el mismo nombre - /* const handleCustomer = (reviews: TReview[]) => { - let k: TReviewUsername[] = []; - if (reviews && reviews.length > 0) { - reviews.forEach((r) => { - getCustomerProfile(r.customerEmail).then((res) => { - if (res.status === 200) { - if (reviewUsername?.find((y) => y.reviewId === +r.id) === undefined) - setReviewUsername((p) => [...p!, { username: res.data.username, reviewId: +r.id }]); - } - }); - }); - } - };*/ - const handleProductClicked = (productId: string) => { nav.navigate( "ShoppingPost" as never, @@ -90,10 +66,13 @@ export default function ProductReview(props: any) { {review.shoppingPost.title} </Text> </TouchableOpacity> - <View className="flex-row justify-between"> + <View className="flex-row flex-wrap justify-between"> <Text className="text-[18px] flex-wrap p-[5px] ml-6 mt-3 dark:text-dark-mode-text font-semibold"> {review.description} </Text> + <Text className="text-[18px] flex-wrap p-[5px] ml-6 mt-3 dark:text-dark-mode-text font-semibold"> + {review.customerEmail} + </Text> </View> {review.base64Images ? ( <View className="p-2 scale-50 -mb-28 -mt-28"> diff --git a/src/screens/SellerReviews.tsx b/src/screens/SellerReviews.tsx index ca2d9c8..1058e5f 100644 --- a/src/screens/SellerReviews.tsx +++ b/src/screens/SellerReviews.tsx @@ -35,8 +35,11 @@ export default function SellerReview(props: any) { reviews.forEach((r) => { getCustomerProfile(r.customerEmail).then((res) => { if (res.status === 200) { - if (reviewUsername?.find((y) => y.reviewId === +r.id) === undefined) - setReviewUsername((p) => [...p!, { username: res.data.username, reviewId: +r.id }]); + if (reviewUsername?.find((y) => y.reviewId === +r.id) === undefined) { + if (res.data.isSuspended) + setReviewUsername((p) => [...p!, { username: "Usuario suspendido", reviewId: +r.id }]); + else setReviewUsername((p) => [...p!, { username: res.data.username, reviewId: +r.id }]); + } } }); }); diff --git a/src/screens/UserProfile.tsx b/src/screens/UserProfile.tsx index 33f43eb..294b324 100644 --- a/src/screens/UserProfile.tsx +++ b/src/screens/UserProfile.tsx @@ -56,6 +56,7 @@ function UserProfile(props: any) { .then((res) => { if (res.status === 200) { let myUser: TCustomer = res.data; + myUser.isSuspended ? ((myUser.picture = ""), (myUser.username = "Usuario suspendido")) : null; setCustomer(myUser); setReviews(myUser.receivedUserReviews); } else console.error("err getting c profile"); diff --git a/src/screens/customer/Notification.tsx b/src/screens/customer/Notification.tsx index 5e5ae7d..952491c 100644 --- a/src/screens/customer/Notification.tsx +++ b/src/screens/customer/Notification.tsx @@ -8,7 +8,7 @@ import { useNavigation } from "@react-navigation/core"; import Loading from "../../components/Loading"; import { Truck } from "phosphor-react-native"; import { handleStatus } from "./Purchase"; -const noitem = require("../../assets/noitem.png"); +const noitem = require("../../../assets/noitem.png"); type ScrollList = { data: TShoppingPost; @@ -19,33 +19,28 @@ export default function Notification(props: any) { const nav = useNavigation(); const { colorScheme } = useColorScheme(); let dark = colorScheme === "dark"; - const [loading, setLoading] = useState(false); + const [loading, setLoading] = useState(true); const [status, setStatus] = useState(false); const [purchase, setPurchase] = useState<TPurchase | undefined>(undefined); const [categoryNotification, setCategoryNotification] = useState<string>(""); useEffect(() => { let cat = props.route.params.category; - setCategoryNotification(cat); + if (cat) setCategoryNotification(cat); if (cat === "promociones") { fetchPromotions(); } else if (cat === "nuevos") { fetchNews(); } else if (cat === "estado") { statusChanged(props.route.params.purchaseId); - } else errorNotification(); - const unsubscribe = nav.addListener("focus", () => { - setLoading(true); - }); - return unsubscribe; - }, [nav, props]); + } else if (!cat || cat === "") errorNotification(); + }, [props]); useEffect(() => { const unsubscribe = nav.addListener("blur", () => { setShoppingPost(undefined); setPurchase(undefined); setStatus(false); - setCategoryNotification(""); }); return unsubscribe; }, [nav]); @@ -175,6 +170,7 @@ export default function Notification(props: any) { const _renderItem = ({ item }: { item: TShoppingPost }) => <ListItem data={item} />; const _header = () => { + console.log(categoryNotification); return categoryNotification === "promociones" ? ( <View className="mt-3"> <Text className="text-2xl font-bold text-center dark:text-dark-mode-text">Rebajas!</Text> @@ -189,7 +185,7 @@ export default function Notification(props: any) { return ( <View className="items-center justify-center flex-1"> <ImageBackground - source={require("../../assets/abstract.jpg")} + source={require("../../../assets/abstract.jpg")} resizeMode="cover" className="w-full h-full bg-no-repeat" blurRadius={6} diff --git a/src/services/Requests.tsx b/src/services/Requests.tsx index 83d142b..9706c76 100644 --- a/src/services/Requests.tsx +++ b/src/services/Requests.tsx @@ -335,6 +335,10 @@ export const toggleSettingNotifications = async (user: string) => { if (user) return iLocal.put(`notifications/setting/${user}`); }; +export const isSuspended = async (user: string) => { + if (user) iLocal.get(`user/isSuspended/${user}`); +}; + // operaciones para localstorage export const storeData = async (key: string, value: string) => { diff --git a/urubuy.d.ts b/urubuy.d.ts index 5c1ce53..c15da65 100644 --- a/urubuy.d.ts +++ b/urubuy.d.ts @@ -57,6 +57,8 @@ export type TCustomer = { givenReviews?: TReview[]; receivedUserReviews?: TUserReview[]; purchases: TPurchase[]; + isBlocked: boolean; + isSuspended: boolean; }; export type TSeller = { -- GitLab From 0f6bfefa3d5700601836e2af376e1c00cc03884b Mon Sep 17 00:00:00 2001 From: "mathias.fernandez.bo" <mathias.fernandez.bo@fing.edu.uy> Date: Sat, 10 Dec 2022 06:31:27 -0300 Subject: [PATCH 6/6] cleaning and fixing --- src/components/Navigation/ImageActiveUser.tsx | 13 ++++ src/components/Navigation/SideMenu.tsx | 12 ++-- src/components/SettingNotifications.tsx | 14 ++-- src/components/SliderSlick.tsx | 2 +- src/screens/Home.tsx | 2 +- src/screens/Login.tsx | 21 ++++-- src/screens/ProductReviews.tsx | 10 ++- src/screens/Settings.tsx | 8 +-- src/screens/ShoppingPost.tsx | 4 +- src/screens/SignUp.tsx | 8 ++- src/screens/UserProfile.tsx | 71 ++++++++++++------- src/screens/customer/Addresses.tsx | 2 +- src/screens/customer/Checkout.tsx | 4 +- src/screens/customer/GiveReview.tsx | 9 ++- src/screens/customer/Logout.tsx | 1 + src/screens/customer/Notification.tsx | 9 ++- src/screens/customer/Profile.tsx | 7 +- src/screens/customer/ShoppingCart.tsx | 13 ++-- src/services/Requests.tsx | 21 ++---- 19 files changed, 134 insertions(+), 97 deletions(-) create mode 100644 src/components/Navigation/ImageActiveUser.tsx diff --git a/src/components/Navigation/ImageActiveUser.tsx b/src/components/Navigation/ImageActiveUser.tsx new file mode 100644 index 0000000..0cc769e --- /dev/null +++ b/src/components/Navigation/ImageActiveUser.tsx @@ -0,0 +1,13 @@ +import { Image, TouchableOpacity } from "react-native"; + +type ImageActiveUserProps = { + onPress: any; +}; + +export const ImageActiveUser: React.FC<ImageActiveUserProps> = ({ onPress }) => { + return ( + <TouchableOpacity className="-left-3.5" onPress={onPress}> + <Image className="scale-[.35] rounded-full" source={require("../../../assets/placeholder.png")} /> + </TouchableOpacity> + ); +}; diff --git a/src/components/Navigation/SideMenu.tsx b/src/components/Navigation/SideMenu.tsx index 1ab5c8d..cd1661e 100644 --- a/src/components/Navigation/SideMenu.tsx +++ b/src/components/Navigation/SideMenu.tsx @@ -26,6 +26,7 @@ import { Trash, Heart, PlusCircle, + Star, } from "phosphor-react-native"; import UserProfile from "../../screens/UserProfile"; import { useColorScheme } from "nativewind"; @@ -37,6 +38,7 @@ import Addresses from "../../screens/customer/Addresses"; import SellerReview from "../../screens/SellerReviews"; import ProductReviews from "../../screens/ProductReviews"; import FAQ from "../Help/FAQ"; +import { ImageActiveUser } from "./ImageActiveUser"; const Drawer = createDrawerNavigator(); @@ -82,6 +84,9 @@ export default function SideMenu() { const [user, setUser] = useState(""); const [cartCounter, setCounter] = useState(0); const [username, setUsername] = useState(""); + const { colorScheme } = useColorScheme(); + let dark = colorScheme === "dark"; + getUsernameActive().then((res) => setUsername(res as string)); getUserActive().then((res) => setUser(res as string)); getUserCart() @@ -92,15 +97,13 @@ export default function SideMenu() { } }) .catch(() => setCounter(0)); - const { colorScheme } = useColorScheme(); - let dark = colorScheme === "dark"; return ( <Drawer.Navigator backBehavior="history" - screenOptions={{ + screenOptions={({ navigation }) => ({ drawerStyle: dark ? { backgroundColor: "#292626" } : { backgroundColor: "white" }, - }} + })} > <Drawer.Screen name="Home" @@ -117,6 +120,7 @@ export default function SideMenu() { drawerIcon: ({ focused }) => ( <House size={22} weight={focused ? "fill" : "duotone"} color={focused ? "#0c35c5" : "grey"} /> ), + headerLeft: () => <ImageActiveUser onPress={navigation.toggleDrawer} />, /*header carrito */ headerRight: (focus) => ( <View className="flex-row items-center justify-center"> diff --git a/src/components/SettingNotifications.tsx b/src/components/SettingNotifications.tsx index 8beb39e..135c34b 100644 --- a/src/components/SettingNotifications.tsx +++ b/src/components/SettingNotifications.tsx @@ -40,10 +40,9 @@ export default function SettingNotifications() { setExpoPushToken(token!); manageSentToken(token); }); - let k: any; + // This listener is fired whenever a notification is received while the app is foregrounded notificationListener.current = Notifications.addNotificationReceivedListener((notification: any) => { - k = notification.request.content.data.category; setNotification(notification); setData({ title: notification.request.content.title, @@ -55,23 +54,22 @@ export default function SettingNotifications() { // This listener when is tapped responseListener.current = Notifications.addNotificationResponseReceivedListener(() => { - // if (notificationData.category === 'promociones') { // filter by category of notifications - k !== "" - ? k === "estado" + notificationData.category && notificationData.category !== "" + ? notificationData.category === "estado" ? nav.navigate( "Notification" as never, { - category: k, + category: notificationData.category, purchaseId: notificationData.purchaseId, } as never, ) : nav.navigate( "Notification" as never, { - category: k, + category: notificationData.category, } as never, ) - : console.log("no category"); + : console.error("no category"); }) as never; }, [notificationData, nav]); diff --git a/src/components/SliderSlick.tsx b/src/components/SliderSlick.tsx index 7f34809..2126cb8 100644 --- a/src/components/SliderSlick.tsx +++ b/src/components/SliderSlick.tsx @@ -1,6 +1,6 @@ import React from "react"; import Slick from "react-native-slick"; -import { Dimensions, Image, View, Text } from "react-native"; +import { Dimensions, Image, View } from "react-native"; import { ImageZoom } from "@likashefqet/react-native-image-zoom/src/index"; const srcPlaceholder = require("../../assets/noitem.png"); const placeholder = Image.resolveAssetSource(srcPlaceholder).uri; diff --git a/src/screens/Home.tsx b/src/screens/Home.tsx index 904271e..974e6c5 100644 --- a/src/screens/Home.tsx +++ b/src/screens/Home.tsx @@ -232,7 +232,7 @@ export default function Home() { } }) .catch((err) => { - console.log(err); + console.error(err); setLoading(false); }) .finally(() => setLoading(false)); diff --git a/src/screens/Login.tsx b/src/screens/Login.tsx index c14801d..1799883 100644 --- a/src/screens/Login.tsx +++ b/src/screens/Login.tsx @@ -2,7 +2,15 @@ import React, { useState, useEffect } from "react"; import { Image, Alert, Text, TouchableOpacity, View, Modal, ActivityIndicator } from "react-native"; import { TextInput } from "react-native-paper"; import { useNavigation } from "@react-navigation/core"; -import { getIdUsuario, getInfoUser, login, resetPassword, sendToken, storeData } from "../services/Requests"; +import { + getCustomerProfile, + getIdUsuario, + getInfoUser, + login, + resetPassword, + sendToken, + storeData, +} from "../services/Requests"; import { ScrollView, KeyboardAvoidingView, Platform } from "react-native"; import myStyle from "../../assets/styles"; import CustomInput from "../components/CustomInput"; @@ -51,17 +59,20 @@ export default function Login() { storeData("email", res.data.email as string); storeData("username", res.data.preferred_username as string); storeData("idUser", res.data.sub as string); - getNotificationToken(); + getCustomerProfile(res.data.email).then((res: any) => { + if (res.status === 200) storeData("userImg", res.data.picture as string); + }); + nav.navigate("Home" as never); }) .catch((err) => { - console.log(err); + console.error(err); }); } }) .catch((err: any) => { if (err.response.data) { - console.log(err.response.data.error_description); + console.error(err.response.data.error_description); if (err.response.status === 401 && err.response.data.error_description === "Invalid user credentials") Alert.alert("Credenciales incorrectas, verifique"); else if (err.response.status === 400 && err.response.data.error_description === "Account is not fully set up") @@ -111,7 +122,7 @@ export default function Login() { }); }) .catch((err: any) => { - console.log(err.response.data); + console.error(err.response.data); }) .finally(() => setLoading(false)); }; diff --git a/src/screens/ProductReviews.tsx b/src/screens/ProductReviews.tsx index a4b5c5c..03cbdf0 100644 --- a/src/screens/ProductReviews.tsx +++ b/src/screens/ProductReviews.tsx @@ -70,9 +70,13 @@ export default function ProductReview(props: any) { <Text className="text-[18px] flex-wrap p-[5px] ml-6 mt-3 dark:text-dark-mode-text font-semibold"> {review.description} </Text> - <Text className="text-[18px] flex-wrap p-[5px] ml-6 mt-3 dark:text-dark-mode-text font-semibold"> - {review.customerEmail} - </Text> + <TouchableOpacity + onPress={() => nav.navigate("UserProfile" as never, { email: review.customerEmail } as never)} + > + <Text className="text-[18px] flex-wrap p-[5px] mr-3 dark:text-dark-mode-text font-semibold"> + {review.customerEmail} + </Text> + </TouchableOpacity> </View> {review.base64Images ? ( <View className="p-2 scale-50 -mb-28 -mt-28"> diff --git a/src/screens/Settings.tsx b/src/screens/Settings.tsx index 36de2d1..5bbfdbb 100644 --- a/src/screens/Settings.tsx +++ b/src/screens/Settings.tsx @@ -79,7 +79,7 @@ function Settings() { setNtfEnabled(res.data.notificationsEnabled); }) .catch((err) => { - console.log(err.response.data); + console.error(err.response.data); alert("error al obtener perfil de usuario"); }); } @@ -142,13 +142,13 @@ function Settings() { } }) .catch((err) => { - console.log(err.response.data); + console.error(err.response.data); if (err.response.status === 409) Alert.alert(err.response.data); }); } }) .catch((err: any) => { - console.log(err.response.data.error_description); + console.error(err.response.data.error_description); if (err.response.status === 401 && err.response.data.error_description === "Invalid user credentials") Alert.alert("Credenciales incorrectas"); else Alert.alert("Problema interno, intente luego"); @@ -164,7 +164,7 @@ function Settings() { setNtfEnabled(r); } }) - .catch((e) => console.log(e.response.data)); + .catch((e) => console.error(e.response.data)); }; return ( diff --git a/src/screens/ShoppingPost.tsx b/src/screens/ShoppingPost.tsx index c408d3f..6a52796 100644 --- a/src/screens/ShoppingPost.tsx +++ b/src/screens/ShoppingPost.tsx @@ -38,7 +38,7 @@ export default function ShoppingPost(props: any) { setShoppingPost(res.data); handleShowSeller(res.data.sellerEmail); }) - .catch((err) => console.log(err)) + .catch((err) => console.error(err)) .finally(() => setLoading(false)); const unsubscribe = nav.addListener("focus", () => { @@ -71,7 +71,7 @@ export default function ShoppingPost(props: any) { function handleProfile(seller: string) { if (seller) nav.navigate("UserProfile" as never, { email: seller } as never); - else console.log("seller wrong"); + else console.error("seller wrong"); } function handleShowSeller(email: string) { diff --git a/src/screens/SignUp.tsx b/src/screens/SignUp.tsx index af9dc43..ba194fa 100644 --- a/src/screens/SignUp.tsx +++ b/src/screens/SignUp.tsx @@ -52,6 +52,9 @@ export default function SignUp() { picture: image, givenUserReviews: undefined, receivedUserReviews: undefined, + purchases: [], + isBlocked: false, + isSuspended: false, }; let userKc: TUserKC = { email: email, @@ -73,7 +76,7 @@ export default function SignUp() { }) .catch((err: any) => { let error = err.response.data.errorMessage; - console.log(err); + console.error(err); Alert.alert("Error al registrarse", error as string); }); } else Alert.alert("Formulario inválido"); @@ -92,7 +95,7 @@ export default function SignUp() { }); }) .catch((err: any) => { - console.log(err.response.data); + console.error(err.response.data); }); }; @@ -115,7 +118,6 @@ export default function SignUp() { if (!result.cancelled) { setImage(result.base64!); - console.log(result.fileSize); } }; diff --git a/src/screens/UserProfile.tsx b/src/screens/UserProfile.tsx index 294b324..f4303df 100644 --- a/src/screens/UserProfile.tsx +++ b/src/screens/UserProfile.tsx @@ -16,9 +16,10 @@ function UserProfile(props: any) { const [customer, setCustomer] = useState<TCustomer | undefined>(undefined); const [showReviews, setShowReviews] = useState(false); const [reviews, setReviews] = useState<TUserReview[] | undefined>(undefined); - const nav = useNavigation(); + const [customerSuspended, setCustomerSuspended] = useState<boolean | undefined>(false); const [loading, setLoading] = useState(false); const { colorScheme } = useColorScheme(); + const nav = useNavigation(); const dark = colorScheme === "dark"; useEffect(() => { @@ -56,13 +57,13 @@ function UserProfile(props: any) { .then((res) => { if (res.status === 200) { let myUser: TCustomer = res.data; - myUser.isSuspended ? ((myUser.picture = ""), (myUser.username = "Usuario suspendido")) : null; setCustomer(myUser); + setCustomerSuspended(false); setReviews(myUser.receivedUserReviews); } else console.error("err getting c profile"); }) .catch((err) => { - console.log(err.response.data); + console.error(err.response.data); Alert.alert("user no encontrado"); nav.canGoBack(); }); @@ -126,7 +127,9 @@ function UserProfile(props: any) { {user?.picture !== undefined && user?.picture !== "" && user?.picture !== null ? ( <Image source={ - user.picture.includes("http") + customerSuspended + ? require("../../assets/placeholder.png") + : user.picture.includes("http") ? { uri: user.picture } : user.picture.includes("data:image") ? { uri: user?.picture } @@ -141,28 +144,42 @@ function UserProfile(props: any) { className="w-[137px] h-[137px] mt-[35px] ml-3 rounded-full" /> )} - <View className="max-h-[250px] max-w-[250px] absolute top-[70] left-[160] border-[black]"> - <Text className="text-[black] dark:text-dark-mode-text text-[20px] font-semibold ml-[15px]"> - {user.username} - </Text> - <View className="mt-3 ml-4"> - <StarRatingDisplay - rating={user?.averageRating ? user?.averageRating : 1} - starStyle={{ marginHorizontal: -2 }} - color={dark ? "#cf8c40" : "blue"} - /> + {!customerSuspended ? ( + <View className="max-h-[250px] max-w-[250px] absolute top-[70] left-[160] border-[black]"> + <Text className="text-[black] dark:text-dark-mode-text text-[20px] font-semibold ml-[15px]"> + {user.username} + </Text> + <View className="mt-3 ml-4"> + <StarRatingDisplay + rating={user?.averageRating ? user?.averageRating : 1} + starStyle={{ marginHorizontal: -2 }} + color={dark ? "#cf8c40" : "blue"} + /> + </View> </View> - </View> - - <CustomButton - onPress={() => setShowReviews(!showReviews)} - value={"Ver calificaciones"} - style={undefined} - isDisabled={false} - /> - <View className={Platform.OS === "android" ? "left-[40px] bottom-[12px]" : "left-[72px] bottom-7"}> - <Star size={20} color="white" weight="duotone" /> - </View> + ) : ( + <View className="max-h-[250px] max-w-[250px] absolute top-[70] left-[160] border-[black] flex-row"> + <Text className="text-[black] dark:text-dark-mode-text text-[20px] font-semibold ml-[15px] line-through decoration-custom-red"> + {user.username} + </Text> + <Text className="text-[black] dark:text-dark-mode-text text-[20px] font-semibold ml-[15px]"> + {"suspendido"} + </Text> + </View> + )} + {!customerSuspended && ( + <> + <CustomButton + onPress={() => setShowReviews(!showReviews)} + value={"Ver calificaciones"} + style={undefined} + isDisabled={false} + /> + <View className={Platform.OS === "android" ? "left-[40px] bottom-[12px]" : "left-[72px] bottom-7"}> + <Star size={20} color="white" weight="duotone" /> + </View> + </> + )} </> ); }; @@ -225,7 +242,7 @@ function UserProfile(props: any) { <View className="justify-between"> <Text className="text-[#000] mt-2 dark:text-dark-mode-text text-[18px] font-semibold"> - {data.customerEmail}: + {customer ? data.sellerEmail : data.customerEmail} </Text> <Card.FeaturedSubtitle className="font-semibold text-[18px] p-2 text-[#000] dark:text-dark-mode-text my-auto"> {data.description} @@ -248,7 +265,7 @@ function UserProfile(props: any) { ) : customer ? ( renderCustomer(customer) ) : seller ? ( - renderSeller(seller as TSeller) + renderSeller(seller) ) : null} {showReviews ? ( reviews && reviews.length > 0 ? ( diff --git a/src/screens/customer/Addresses.tsx b/src/screens/customer/Addresses.tsx index e36f3fa..941bd9f 100644 --- a/src/screens/customer/Addresses.tsx +++ b/src/screens/customer/Addresses.tsx @@ -35,7 +35,7 @@ export default function Addresses(props: any) { deleteAddressCustomer(user, addr) .then((r: any) => (r.status === 200 ? setAddresses(r.data) : Alert.alert("Error al borrar la dirección"))) .catch((e) => { - console.log(e); + console.error(e); Alert.alert("Error al borrar la dirección"); }); }, diff --git a/src/screens/customer/Checkout.tsx b/src/screens/customer/Checkout.tsx index 9e6084e..021a9a5 100644 --- a/src/screens/customer/Checkout.tsx +++ b/src/screens/customer/Checkout.tsx @@ -71,7 +71,7 @@ export default function Checkout(props: any) { console.log(checkout?.total); // total no puede salir con mas de 2 decimales openLink(checkout?.total); - } else console.log("total failed"); + } else console.error("total failed"); }; type ScrollList = { @@ -175,7 +175,7 @@ export default function Checkout(props: any) { await removeData("hasCheckout"); } }) - .catch((err) => console.log(err.response.data)); + .catch((err) => console.error(err.response.data)); }; return ( diff --git a/src/screens/customer/GiveReview.tsx b/src/screens/customer/GiveReview.tsx index 9f0eb8f..9066de6 100644 --- a/src/screens/customer/GiveReview.tsx +++ b/src/screens/customer/GiveReview.tsx @@ -90,13 +90,11 @@ export default function GiveReview(props: any) { base64: image.base64, }; if (photos?.some((p) => p.titlePhoto === photo.titlePhoto)) { - console.log("ya existe foto"); + console.warn("ya existe foto"); } else { setPhotos((prev) => [...prev!, photo]); setImages((prev) => [...prev!, image.base64]); } - console.log(image.fileSize); - console.log(photos?.length); setLoading(false); }); } else setLoading(false); @@ -143,7 +141,8 @@ export default function GiveReview(props: any) { if (res.status === 200) Alert.alert("Gracias por calificar"); }) .catch((err) => { - Alert.alert("Imposible calificar", err.response.data); + if (err.response.status === 403) Alert.alert("Ya calificaste este producto"); + else Alert.alert("Imposible calificar", err.response.data); }) .finally(() => { setReviewComment(""); @@ -156,7 +155,7 @@ export default function GiveReview(props: any) { const sellerClicked = () => { if (sellerEmail) nav.navigate("UserProfile" as never, { email: sellerEmail } as never); - else console.log("seller wrong"); + else console.error("seller wrong"); }; return ( diff --git a/src/screens/customer/Logout.tsx b/src/screens/customer/Logout.tsx index bee67a3..085938f 100644 --- a/src/screens/customer/Logout.tsx +++ b/src/screens/customer/Logout.tsx @@ -8,6 +8,7 @@ export const removeDataStored = async () => { await removeData("email"); await removeData("tokenUser"); await removeData("username"); + await removeData("userImg"); }; export default function Logout() { diff --git a/src/screens/customer/Notification.tsx b/src/screens/customer/Notification.tsx index 952491c..61f8a59 100644 --- a/src/screens/customer/Notification.tsx +++ b/src/screens/customer/Notification.tsx @@ -38,7 +38,7 @@ export default function Notification(props: any) { useEffect(() => { const unsubscribe = nav.addListener("blur", () => { - setShoppingPost(undefined); + setShoppingPost([]); setPurchase(undefined); setStatus(false); }); @@ -55,7 +55,7 @@ export default function Notification(props: any) { } }) .catch((err: any) => { - console.log(err.response.data); + console.error(err.response.data); }) .finally(() => { setLoading(false); @@ -68,7 +68,7 @@ export default function Notification(props: any) { .then((res) => { setPurchase(res?.data); }) - .catch((e) => console.log(e)) + .catch((e) => console.error(e)) .finally(() => { setLoading(false); }); @@ -86,7 +86,7 @@ export default function Notification(props: any) { } }) .catch((err: any) => { - console.log(err.response.data); + console.error(err.response.data); }) .finally(() => {}); } @@ -170,7 +170,6 @@ export default function Notification(props: any) { const _renderItem = ({ item }: { item: TShoppingPost }) => <ListItem data={item} />; const _header = () => { - console.log(categoryNotification); return categoryNotification === "promociones" ? ( <View className="mt-3"> <Text className="text-2xl font-bold text-center dark:text-dark-mode-text">Rebajas!</Text> diff --git a/src/screens/customer/Profile.tsx b/src/screens/customer/Profile.tsx index 07c7e87..5fae569 100644 --- a/src/screens/customer/Profile.tsx +++ b/src/screens/customer/Profile.tsx @@ -47,6 +47,8 @@ function Profile() { receivedUserReviews: res.data.receivedUserReviews, givenReviews: res.data.givenReviews, purchases: res.data.purchases, + isBlocked: res.data.isBlocked, + isSuspended: res.data.isSuspended, }; setUser(myUser); } else console.error("getting profile"); @@ -89,7 +91,6 @@ function Profile() { }); if (!result.cancelled) { - console.log(result.fileSize); updateProfile(result.base64!, user?.username!).finally(() => { getInitialData(); }); @@ -115,14 +116,14 @@ function Profile() { }) .catch((er) => { setLoading(false); - console.log(er); + console.error(er); }); } }); }) .catch((er) => { setLoading(false); - console.log(er); + console.error(er); }); }; diff --git a/src/screens/customer/ShoppingCart.tsx b/src/screens/customer/ShoppingCart.tsx index 2d239a8..9151d7c 100644 --- a/src/screens/customer/ShoppingCart.tsx +++ b/src/screens/customer/ShoppingCart.tsx @@ -134,10 +134,10 @@ export default function ShoppingCart() { setShoppingPost((prevState) => [...prevState!, post]); } }) - .catch((err) => console.log(err.response.data)); + .catch((err) => console.error(err.response.data)); }); }) - .catch((err) => console.log(err.response.data)) + .catch((err) => console.error(err.response.data)) .finally(() => setLoading(false)); }; @@ -288,12 +288,12 @@ export default function ShoppingCart() { shoppingCartId: shoppingCart?.id, } as never, ); - } else console.log("no hay checkout"); + } else console.error("no hay checkout"); }); } }) .catch(async (err) => { - console.log(err.response.data); + console.error(err.response.data); }); } }; @@ -344,7 +344,6 @@ export default function ShoppingCart() { if (posts?.length! > 1) { let seller = posts?.find((x) => x.id === productId)?.sellerEmail; - console.log(seller); let cp: TCheckout[] = checkoutProducts!; posts?.forEach((x) => { if (x.id !== productId) { @@ -390,9 +389,9 @@ export default function ShoppingCart() { if (res.status === 200) { setNewAddress(false); setCustomerAddresses(res.data.addresses); - } else console.log(res); + } else console.warn(res); }) - .catch((err) => console.log(err.response.data)) + .catch((err) => console.error(err.response.data)) .finally(() => { getCart(); }); diff --git a/src/services/Requests.tsx b/src/services/Requests.tsx index 9706c76..a936551 100644 --- a/src/services/Requests.tsx +++ b/src/services/Requests.tsx @@ -45,7 +45,6 @@ export const resetPassword = async (idUser: string) => { Authorization: "Bearer " + token, }, }; - console.log("pido reset"); return iAdmin_KC.put(`/users/${idUser}/reset-password-email`, undefined, header); }; @@ -66,7 +65,6 @@ export const getAdminToken = async () => { }); const res = await iAuth.post("/token", params.toString(), header); - console.log("pido tokenAdmin"); await storeData("tokenAdmin", res.data.access_token); }; @@ -84,8 +82,6 @@ export const login = (user: TUserKC) => { username: user.email, password: user.password, }); - - console.log("pido login"); return iAuth.post("/token", params.toString(), header); }; @@ -97,7 +93,6 @@ export const getInfoUser = async () => { Authorization: "Bearer " + token, }, }; - console.log("pido userinfo"); return iAuth.get("/userinfo", header); }; @@ -126,8 +121,6 @@ export const signUp = async (user: TUserKC) => { ], realmRoles: ["default-roles-urubuy"], }; - - console.log("pido signup"); return iAdmin_KC.post("/users", data, header); } else console.error("token invalido"); }; @@ -146,7 +139,7 @@ export const signUpLocal = (user: TCustomer) => { .then((res) => { if (res.status === 200) console.log("usuario dado de alta localmente"); }) - .catch((err) => console.log(err)); + .catch((err) => console.error(err)); }; export const logoutUser = async (isAdmin: boolean) => { @@ -161,7 +154,6 @@ export const logoutUser = async (isAdmin: boolean) => { Authorization: "Bearer " + token, }, }; - console.log("pido logout"); return iAdmin_KC.post(`/users/${idUser}/logout`, undefined, header); } }; @@ -175,8 +167,6 @@ export const getIdUsuario = async () => { Authorization: "Bearer " + token, }, }; - - console.log("pido id users"); return iAdmin_KC.get("/users", header); } else console.warn("fail getIdUsuario"); }; @@ -191,7 +181,6 @@ export const sendEmail = async () => { Authorization: "Bearer " + token, }, }; - console.log("pido sendmail"); return iAdmin_KC.put(`/users/${idUser}/send-verify-email`, undefined, header); } }; @@ -214,7 +203,7 @@ export const sendToken = async (myToken: string) => { }; } - console.log(tenant); + console.warn(tenant); if (tenant.token !== undefined) { return iLocal.post(`notifications/addXP`, tenant); } @@ -345,7 +334,7 @@ export const storeData = async (key: string, value: string) => { try { await AsyncStorage.setItem(key, value); } catch (error) { - console.log(error); + console.error(error); } }; @@ -354,7 +343,7 @@ export const getData = async (key: string) => { const value = await AsyncStorage.getItem(key); if (value !== null) return value as string; } catch (error) { - console.log(error); + console.error(error); } }; @@ -362,6 +351,6 @@ export const removeData = async (key: string) => { try { return await AsyncStorage.removeItem(key); } catch (error) { - console.log(error); + console.error(error); } }; -- GitLab