From f6bbc94285f1866f0502d0e575fe83059a9ddbcd Mon Sep 17 00:00:00 2001
From: ivic00 <102467664+ivic00@users.noreply.github.com>
Date: Wed, 7 Aug 2024 18:12:45 +0200
Subject: [PATCH] added firebase profiles
---
app/(auth)/main/index.tsx | 359 +++++++++++++++++++++++++++++++++++++-
package-lock.json | 10 ++
package.json | 1 +
3 files changed, 364 insertions(+), 6 deletions(-)
diff --git a/app/(auth)/main/index.tsx b/app/(auth)/main/index.tsx
index 7d92969..bb90537 100644
--- a/app/(auth)/main/index.tsx
+++ b/app/(auth)/main/index.tsx
@@ -1,7 +1,354 @@
-import {View} from "react-native-ui-lib";
+import React, { useEffect, useState } from "react";
+import { Text, Button, TextInput } from "react-native";
+import firestore from "@react-native-firebase/firestore";
+import auth from "@react-native-firebase/auth";
+import {} from "@react-native-firebase/auth/";
+import { View, TextField, ListItem, Picker } from "react-native-ui-lib";
-export default function Screen() {
- return (
-
- )
-}
\ No newline at end of file
+type ProfileType = "Parent" | "Child" | "Caregiver" | null;
+
+interface User {
+ uid: string;
+ email: string | null;
+}
+
+interface UserProfile {
+ userType: "parent" | "child" | "caregiver";
+ name: string;
+}
+
+interface ParentProfile extends UserProfile {
+ userType: "parent";
+}
+
+interface ChildProfile extends UserProfile {
+ userType: "child";
+ birthday: Date;
+ parentId: string;
+}
+
+interface CaregiverProfile extends UserProfile {
+ userType: "caregiver";
+ //assignedChildrenId: string[];
+ contact: string;
+}
+
+const Screen: React.FC = () => {
+ const [user, setUser] = useState(null);
+ const [profileType, setProfileType] = useState(null);
+ const [email, setEmail] = useState("");
+ const [password, setPassword] = useState("");
+ const [child, setChild] = useState({
+ name: "",
+ birthday: new Date(),
+ userType: "child" as const,
+ parentId: "",
+ });
+ const [caregiver, setCaregiver] = useState({
+ name: "",
+ contact: "",
+ userType: "caregiver",
+ });
+
+ const [children, setChildren] = useState([]);
+ const [caregivers, setCaregivers] = useState([]);
+
+ useEffect(() => {
+ const isDevelopment = __DEV__;
+
+ if (isDevelopment) {
+ firestore().useEmulator("localhost", 8080);
+ auth().useEmulator("http://127.0.0.1:9099");
+ }
+
+ const unsubscribe = auth().onAuthStateChanged(async (firebaseUser) => {
+ if (firebaseUser) {
+ const userObj: User = {
+ uid: firebaseUser.uid,
+ email: firebaseUser.email,
+ };
+ setUser(userObj);
+
+ try {
+ const documentSnapshot = await firestore()
+ .collection("Users")
+ .doc(firebaseUser.uid)
+ .get();
+ if (documentSnapshot.exists) {
+ setProfileType(documentSnapshot.data()?.profileType || null);
+ }
+ } catch (error) {
+ console.error("Error fetching user profile type:", error);
+ setProfileType(null);
+ }
+ } else {
+ setUser(null);
+ setProfileType(null);
+ }
+ });
+
+ return unsubscribe;
+ }, []);
+
+ const fetchChildren = async () => {
+ if (user) {
+ const childrenProfiles = await getChildrenByParentId(user.uid);
+ setChildren(childrenProfiles);
+ }
+ };
+ const fetchCaregivers = async () => {
+ const caregiverProfiles = await getCaregivers();
+ setCaregivers(caregiverProfiles);
+ };
+
+ useEffect(() => {
+ fetchChildren();
+ fetchCaregivers();
+ }, []);
+ useEffect(() => {
+ fetchChildren();
+ fetchCaregivers();
+ }, [user]);
+
+ const getCaregivers = async (
+ ): Promise => {
+ try {
+ const snapshot = await firestore()
+ .collection("Profiles")
+ .where("userType", "==", "caregiver")
+ .get();
+
+ const caregivers: CaregiverProfile[] = snapshot.docs.map((doc) => {
+ const data = doc.data();
+ return {
+ ...data,
+ } as CaregiverProfile;
+ });
+
+ return caregivers;
+ } catch (error) {
+ console.error("Error retrieving caregivers:", error);
+ return [];
+ }
+ };
+
+ const getChildrenByParentId = async (
+ parentId: string
+ ): Promise => {
+ try {
+ const snapshot = await firestore()
+ .collection("Profiles")
+ .where("userType", "==", "child")
+ .where("parentId", "==", parentId)
+ .get();
+
+ const children: ChildProfile[] = snapshot.docs.map((doc) => {
+ const data = doc.data();
+ return {
+ ...data,
+ birthday: data.birthday.toDate(),
+ } as ChildProfile;
+ });
+
+ return children;
+ } catch (error) {
+ console.error("Error retrieving child users:", error);
+ return [];
+ }
+ };
+
+ const handleLogin = async () => {
+ try {
+ await auth().signInWithEmailAndPassword(email, password);
+ console.log("User signed in!");
+ } catch (error) {
+ console.error("Error during sign in:", error);
+ }
+ };
+
+ const handleSignOut = async () => {
+ try {
+ await auth().signOut();
+ } catch (error) {
+ console.error("error during Sign out: ", error);
+ }
+ };
+
+ const handleProfileTypeSelection = (type: ProfileType) => {
+ if (user) {
+ setProfileType(type);
+
+ firestore()
+ .collection("Users")
+ .doc(user.uid)
+ .set({ profileType: type }, { merge: true });
+ }
+ };
+
+ const handleNewChild = async (newChild: ChildProfile) => {
+ try {
+ if (user) newChild.parentId = user.uid;
+ await firestore().collection("Profiles").add(newChild);
+ } catch (error) {
+ console.error(error);
+ } finally {
+ setChild((prev) => ({ ...prev, name: "" }));
+ }
+ };
+
+ const handleNewCaregiver = async (newCaregiver: CaregiverProfile) => {
+ try {
+ await firestore().collection("Profiles").add(newCaregiver);
+ } catch (error) {
+ console.error(error);
+ } finally {
+ setCaregiver((prev) => ({ ...prev, name: "", contact: "" }));
+ }
+ };
+
+ const renderLogin = () => (
+
+
+
+
+ Choose Profile Type:
+
+ );
+
+ const renderParentControls = () => (
+
+ Parent Dashboard
+
+ );
+
+ const renderChildControls = () => (
+
+ Child Dashboard
+
+ );
+
+ const renderCaregiverControls = () => (
+
+ Caregiver Dashboard
+
+ );
+
+ return (
+
+ {user ? (
+
+ {profileType === "Parent" && renderParentControls()}
+ {profileType === "Child" && renderChildControls()}
+ {profileType === "Caregiver" && renderCaregiverControls()}
+
+
+ setChild((prevChild) => ({
+ ...prevChild,
+ name: value,
+ }))
+ }
+ enableErrors
+ validate={["required", (value: string) => value.length > 6]}
+ validationMessage={[
+ "Field is required",
+ "Email is invalid",
+ "Password is too short",
+ ]}
+ showCharCounter
+ maxLength={30}
+ />
+ {
+ handleNewChild(child);
+ fetchChildren();
+ }}
+ />
+
+ setCaregiver((prevCaregiver) => ({
+ ...prevCaregiver,
+ name: value,
+ }))
+ }
+ enableErrors
+ validate={["required", (value: string) => value.length > 6]}
+ validationMessage={["Field is required"]}
+ showCharCounter
+ maxLength={30}
+ />
+
+ setCaregiver((prevCaregiver) => ({
+ ...prevCaregiver,
+ contact: value,
+ }))
+ }
+ enableErrors
+ validate={[
+ "number",
+ "required",
+ (value: string) => value.length > 9,
+ ]}
+ validationMessage={["Field is required"]}
+ showCharCounter
+ maxLength={30}
+ />
+ {
+ handleNewCaregiver(caregiver);
+ fetchCaregivers();
+ }}
+ />
+
+ Children:
+ {children.map((child) => (
+
+ Name: {child.name}
+
+ {caregivers.map((item) => (
+
+
+
+ ))}
+
+
+ ))}
+
+
+ ) : (
+ renderLogin()
+ )}
+
+ );
+};
+
+export default Screen;
diff --git a/package-lock.json b/package-lock.json
index eccf16f..e2a7e5b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14,6 +14,7 @@
"@react-native-firebase/app": "^20.3.0",
"@react-native-firebase/auth": "^20.3.0",
"@react-native-firebase/crashlytics": "^20.3.0",
+ "@react-native-firebase/firestore": "^20.3.0",
"@react-navigation/drawer": "^6.7.2",
"@react-navigation/native": "^6.0.2",
"expo": "~51.0.24",
@@ -7091,6 +7092,15 @@
}
}
},
+ "node_modules/@react-native-firebase/firestore": {
+ "version": "20.3.0",
+ "resolved": "https://registry.npmjs.org/@react-native-firebase/firestore/-/firestore-20.3.0.tgz",
+ "integrity": "sha512-bCFjM5FBshsyRD8UQfPlzbHoOshNZ+oVSFiWP6pz1jp9mumTfTaEi0pEqqRhGuxX2mDA/1lJQT44RXfHTAQ3yQ==",
+ "license": "Apache-2.0",
+ "peerDependencies": {
+ "@react-native-firebase/app": "20.3.0"
+ }
+ },
"node_modules/@react-native/assets-registry": {
"version": "0.74.85",
"resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.74.85.tgz",
diff --git a/package.json b/package.json
index 90dc306..2f47fc3 100644
--- a/package.json
+++ b/package.json
@@ -21,6 +21,7 @@
"@react-native-firebase/app": "^20.3.0",
"@react-native-firebase/auth": "^20.3.0",
"@react-native-firebase/crashlytics": "^20.3.0",
+ "@react-native-firebase/firestore": "^20.3.0",
"@react-navigation/drawer": "^6.7.2",
"@react-navigation/native": "^6.0.2",
"expo": "~51.0.24",