diff --git a/package-lock.json b/package-lock.json index 941fad147d1058a12b502bee1ca85a89cb21da9a..92e1da693b115d4378acc6078d1a50427520f480 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,11 +21,13 @@ "expo-constants": "~14.2.1", "expo-status-bar": "~1.4.4", "firebase": "^9.9.3", + "radio-buttons-react-native": "^1.0.4", "react": "18.2.0", "react-dom": "18.2.0", "react-native": "0.71.14", "react-native-gesture-handler": "~2.9.0", "react-native-gifted-chat": "^2.4.0", + "react-native-radio-buttons-group": "^3.0.5", "react-native-safe-area-context": "4.5.0", "react-native-screens": "~3.20.0", "react-native-web": "~0.18.10", @@ -14634,6 +14636,11 @@ } ] }, + "node_modules/radio-buttons-react-native": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/radio-buttons-react-native/-/radio-buttons-react-native-1.0.4.tgz", + "integrity": "sha512-5AKM/p3a9mykQ1BCIbBnHrDwXZZ6iJuDEDFaiNb2Pa2Nx9EgUMgU5owcrU9g9eaK7didA5rJ3yAUKGnyfhBqcw==" + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -14908,6 +14915,11 @@ "react-native": "*" } }, + "node_modules/react-native-radio-buttons-group": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/react-native-radio-buttons-group/-/react-native-radio-buttons-group-3.0.5.tgz", + "integrity": "sha512-4JQAUJFW2D0txqgktLL1QyXuy6yUWg3r8O2+h1XLUHV9Jby8xnL6IgJsoew3jxXM6uwN+zQcya1wGTRgEB+/KQ==" + }, "node_modules/react-native-safe-area-context": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.5.0.tgz", diff --git a/package.json b/package.json index 9c466d2e70bfe8b23ec51a210433a048446cb08a..01630d105ca8b7eb5e67604f08478c0fa79c66b9 100644 --- a/package.json +++ b/package.json @@ -23,11 +23,13 @@ "expo-constants": "~14.2.1", "expo-status-bar": "~1.4.4", "firebase": "^9.9.3", + "radio-buttons-react-native": "^1.0.4", "react": "18.2.0", "react-dom": "18.2.0", "react-native": "0.71.14", "react-native-gesture-handler": "~2.9.0", "react-native-gifted-chat": "^2.4.0", + "react-native-radio-buttons-group": "^3.0.5", "react-native-safe-area-context": "4.5.0", "react-native-screens": "~3.20.0", "react-native-web": "~0.18.10", diff --git a/screens/ScreenNavigator.js b/screens/ScreenNavigator.js index 19bba0ff59aa85a64d35b4cf42c95da1c22ae64e..0d74a81ec37a1fc50319721304059807ce7d4467 100644 --- a/screens/ScreenNavigator.js +++ b/screens/ScreenNavigator.js @@ -1,6 +1,6 @@ -import React, { useState, useLayoutEffect, useEffect } from "react"; +import React, { useState, useLayoutEffect } from "react"; import { auth, database } from "../config/firebase"; -import { collection, query, onSnapshot, where, and, addDoc, getDocs } from "firebase/firestore"; +import { collection, query, where, and, addDoc, getDocs } from "firebase/firestore"; import { createStackNavigator } from "@react-navigation/stack"; import Chat from "./tabs/Chat"; import ChatUid from "./tabs/ChatUid"; diff --git a/screens/auth/Signup.js b/screens/auth/Signup.js index 8d9a2ee7fa18ca0a481bcee4a63101bff248bca3..a5c71c2f43454a5cfdbcde88001211e64f2d5c3d 100644 --- a/screens/auth/Signup.js +++ b/screens/auth/Signup.js @@ -2,31 +2,31 @@ import React, { useState } from "react"; import { StyleSheet, Text, View, Button, TextInput, Image, SafeAreaView, TouchableOpacity, StatusBar, Alert } from "react-native"; import { createUserWithEmailAndPassword } from "firebase/auth"; import { auth } from "../../config/firebase"; +import RadioGroup from 'react-native-radio-buttons-group'; const backImage = require("../../assets/backImage.png"); +import { collection, addDoc } from "firebase/firestore"; +import { database } from "../../config/firebase"; + export default function Signup({ navigation }) { const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [name, setName] = useState(""); + const [role, setRole] = useState("") + const [error, setError] = useState("") const onHandleSignup = () => { + if (!role) { setError("Please choose a role!"); return; } if (email !== "" && password !== "") { createUserWithEmailAndPassword(auth, email, password) .then((userCredential) => { - // Registered - const user = userCredential.user; - updateProfile(user, { + addDoc(collection(database, "profiles"), { + createdAt: new Date(), + userId: userCredential.user.uid, + role: role, displayName: name, - photoURL: avatar ? avatar : 'https://gravatar.com/avatar/94d45dbdba988afacf30d916e7aaad69?s=200&d=mp&r=x', - }) - .then(() => { - alert('Registered, please login.'); - }) - .catch((error) => { - const errorCode = error.code; - const errorMessage = error.message; - alert(errorCode, errorMessage); - }) + photoURL: 'https://gravatar.com/avatar/94d45dbdba988afacf30d916e7aaad69?s=200&d=mp&r=x', + }); }) .catch((err) => Alert.alert("Login error", err.message)); } @@ -67,6 +67,32 @@ export default function Signup({ navigation }) { value={password} onChangeText={(text) => setPassword(text)} /> + <Text>Please choose one role to join us:</Text> + <RadioGroup + radioButtons={[ + { + id: 'cat-owner', // acts as primary key, should be unique and non-empty string + label: 'Join as a cat owner', + value: 'cat-owner', + labelStyle: { color: "black" }, + containerStyle: { width: "100%", marginLeft: 10 } + }, + { + id: 'cat-sitter', + label: 'Join as a cat sitter', + value: 'cat-sitter', + labelStyle: { color: "black" }, + containerStyle: { width: "100%", marginLeft: 10 } + } + ]} + onPress={setRole} + selectedId={role} + /> + { + error.length <= 0 && ( + <Text style={{ color: "red" }}>{error}</Text> + ) + } {/* TODO: Add a checkbox for role */} <TouchableOpacity style={styles.button} onPress={onHandleSignup}> <Text style={{ fontWeight: "bold", color: "#fff", fontSize: 18 }}> Sign Up</Text> diff --git a/screens/cat-sitter/CatsitterHome.js b/screens/cat-sitter/CatsitterHome.js index d5f95f4232099a82d332033be90faff87cdf35c9..c98617fa01cdcf5ea2bf48e86b7dea99b97c3135 100644 --- a/screens/cat-sitter/CatsitterHome.js +++ b/screens/cat-sitter/CatsitterHome.js @@ -1,5 +1,5 @@ import React, { useEffect, useState, useLayoutEffect } from "react"; -import { View, TouchableOpacity, Text, Pressable, FlatList, Keyboard, Button, PRETT } from "react-native"; +import { View, TouchableOpacity, Text, Pressable, FlatList } from "react-native"; import { useNavigation } from "@react-navigation/native"; import { FontAwesome } from "@expo/vector-icons"; import colors from "../../colors"; @@ -58,7 +58,6 @@ const CatsitterHome = () => { return ( <View style={styles.container}> - <Text>My Profile</Text> <View> {chats.length > 0 ? ( <FlatList @@ -81,7 +80,9 @@ const CatsitterHome = () => { </Pressable> )} /> - ) : <Text style={{ textAlign: "right" }}>No Chat available</Text>} + ) : (<View> + <Text style={{ textAlign: "right" }}>Currently no chat available. Configure your profile to gain more attention</Text> + </View>)} </View> </View> ); diff --git a/screens/cat-sitter/CatsitterSetting.js b/screens/cat-sitter/CatsitterSetting.js index 005fe611d4b43ac55db890cdfedeaa9072e7e6dc..0d74c47c881e69ba85d89d974889b687284527bb 100644 --- a/screens/cat-sitter/CatsitterSetting.js +++ b/screens/cat-sitter/CatsitterSetting.js @@ -1,5 +1,5 @@ import React, { useEffect, useState, useLayoutEffect } from "react"; -import { View, TouchableOpacity, Text, TextInput, StyleSheet } from "react-native"; +import { View, TouchableOpacity, Text, TextInput, StyleSheet, Image } from "react-native"; import { useNavigation } from "@react-navigation/native"; import { FontAwesome } from "@expo/vector-icons"; import colors from "../../colors"; @@ -8,17 +8,38 @@ import { AntDesign } from "@expo/vector-icons"; import { collection, query, onSnapshot, where, and, updateDoc, doc } from "firebase/firestore"; import { auth, database } from "../../config/firebase"; import { DIMENSION_WIDTH } from "../../assets/styles"; - +import Icon from "../../components/Icon"; //When user has role cat sitter //TODO: get profile of cat sitter => If not then has to create //Cat sitter has 2 screens => Profile Setting and Chat List //Check for some needed info => If not go direct to setting screen //Include Chatbox like in cat owner home => OK +const imageStyle = [ + { + borderRadius: 8, + height: 120, + margin: 0, + aspectRatio: 1, + borderWidth: 2, + borderColor: "#FAFAFA" + } +]; + +const nameStyle = [ + { + paddingTop: 10, + paddingBottom: 5, + color: "#363636", + fontSize: 15 + } +]; + const CatsitterSetting = () => { const navigation = useNavigation(); const [displayName, setDisplayName] = useState(""); const [profileId, setProfileId] = useState(); + const [catsitter, setCatsitter] = useState({}) const onSignOut = () => { signOut(auth).catch((error) => console.log("Error logging out: ", error)); @@ -51,8 +72,10 @@ const CatsitterSetting = () => { const unsubscribe = onSnapshot(q, (querySnapshot) => { if (querySnapshot.docs.length > 0) { - setProfileId(querySnapshot.docs[0].id) - setDisplayName(querySnapshot.docs[0].data().displayName || "") + setCatsitter({ + id: querySnapshot.docs[0].id, + displayName: querySnapshot.docs[0].data().displayName || "" + }) } }); return unsubscribe; @@ -77,6 +100,46 @@ const CatsitterSetting = () => { </TouchableOpacity> <View> + <View style={{ + borderRadius: 8, + alignItems: "center", + margin: 10, + elevation: 1, + padding: 10, + width: "95%", + display: "flex", + flexDirection: "column", + overflow: "hidden" + }}> + {/* IMAGE */} + <Image source={{ uri: catsitter.avatar }} style={imageStyle} /> + + {/* MATCHES */} + {/* <View style={styles.matchesCardItem}> + <Text style={styles.matchesTextCardItem}> + <Icon name="heart" color={WHITE} size={13} /> {catsitter.availableTime} + </Text> + </View> */} + <Text >Cat Sitter Address: {catsitter.address}</Text > + <Text >Cat Sitter Postal Code:{catsitter.postalCode} </Text > + + + {/* NAME */} + <Text style={nameStyle}>{catsitter.displayName}</Text> + <Text >Cat Sitter Age: {catsitter.age}</Text > + <Text >Cat Sitter Price Per Night: {catsitter.price}</Text > + + {/* DESCRIPTION */} + <Text style={styles.descriptionCardItem}>{catsitter.description}</Text> + + {/* STATUS */} + <View style={styles.status}> + <View style={catsitter.isOpen ? styles.online : styles.offline} /> + <Text style={styles.statusText}> + {catsitter.isOpen ? "Online" : "Offline"} + </Text> + </View> + </View> <TextInput style={styles.input} placeholder="Display Name"