diff --git a/assets/svgs/ArrowRightIcon.tsx b/assets/svgs/ArrowRightIcon.tsx
new file mode 100644
index 0000000..37e85cf
--- /dev/null
+++ b/assets/svgs/ArrowRightIcon.tsx
@@ -0,0 +1,19 @@
+import * as React from "react"
+import Svg, { SvgProps, Path } from "react-native-svg"
+const ArrowRightIcon = (props: SvgProps) => (
+
+)
+export default ArrowRightIcon
diff --git a/assets/svgs/CircledXIcon.tsx b/assets/svgs/CircledXIcon.tsx
new file mode 100644
index 0000000..9759ef8
--- /dev/null
+++ b/assets/svgs/CircledXIcon.tsx
@@ -0,0 +1,22 @@
+import * as React from "react";
+import Svg, { SvgProps, Path } from "react-native-svg";
+const CircledXIcon = (props: SvgProps) => (
+
+);
+export default CircledXIcon;
diff --git a/assets/svgs/EmailIcon.tsx b/assets/svgs/EmailIcon.tsx
new file mode 100644
index 0000000..47d6e00
--- /dev/null
+++ b/assets/svgs/EmailIcon.tsx
@@ -0,0 +1,17 @@
+import * as React from "react"
+import Svg, { SvgProps, Path } from "react-native-svg"
+const EmailIcon = (props: SvgProps) => (
+
+)
+export default EmailIcon
diff --git a/assets/svgs/QRIcon.tsx b/assets/svgs/QRIcon.tsx
new file mode 100644
index 0000000..f7be63d
--- /dev/null
+++ b/assets/svgs/QRIcon.tsx
@@ -0,0 +1,20 @@
+import * as React from "react"
+import Svg, { SvgProps, Path } from "react-native-svg"
+const QRIcon = (props: SvgProps) => (
+
+)
+export default QRIcon
diff --git a/components/pages/brain_dump/AddBrainDump.tsx b/components/pages/brain_dump/AddBrainDump.tsx
index 00bc3f2..a134f5d 100644
--- a/components/pages/brain_dump/AddBrainDump.tsx
+++ b/components/pages/brain_dump/AddBrainDump.tsx
@@ -1,17 +1,24 @@
-import { View, Text, Button, TextField } from "react-native-ui-lib";
-import React, { useEffect, useState } from "react";
+import {
+ View,
+ Text,
+ Button,
+ TextField,
+ TextFieldRef,
+ TouchableOpacity,
+} from "react-native-ui-lib";
+import React, { useEffect, useState, useRef } from "react";
import { Dialog } from "react-native-ui-lib";
import { PanningDirectionsEnum } from "react-native-ui-lib/src/incubator/panView";
-import CloseXIcon from "@/assets/svgs/CloseXIcon";
-import { Dimensions, StyleSheet } from "react-native";
+import { Dimensions, Keyboard, StyleSheet } from "react-native";
+
import DropModalIcon from "@/assets/svgs/DropModalIcon";
-import MenuIcon from "@/assets/svgs/MenuIcon";
import { useBrainDumpContext } from "@/contexts/DumpContext";
interface IAddBrainDumpProps {
isVisible: boolean;
setIsVisible: (value: boolean) => void;
}
+
const AddBrainDump = ({
addBrainDumpProps,
}: {
@@ -20,7 +27,10 @@ const AddBrainDump = ({
const { addBrainDump } = useBrainDumpContext();
const [dumpTitle, setDumpTitle] = useState("");
const [dumpDesc, setDumpDesc] = useState("");
- const { width, height } = Dimensions.get("screen");
+ const { width } = Dimensions.get("screen");
+
+ // Refs for the two TextFields
+ const descriptionRef = useRef(null);
useEffect(() => {
setDumpDesc("");
@@ -34,14 +44,7 @@ const AddBrainDump = ({
width={width}
panDirection={PanningDirectionsEnum.DOWN}
onDismiss={() => addBrainDumpProps.setIsVisible(false)}
- containerStyle={{
- borderTopRightRadius: 15,
- borderTopLeftRadius: 15,
- backgroundColor: "white",
- padding: 0,
- paddingTop: 3,
- margin: 0,
- }}
+ containerStyle={styles.dialogContainer}
visible={addBrainDumpProps.isVisible}
>
@@ -53,16 +56,15 @@ const AddBrainDump = ({
addBrainDumpProps.setIsVisible(false);
}}
/>
- addBrainDumpProps.setIsVisible(false)}
- />
+ addBrainDumpProps.setIsVisible(false)}>
+
+
@@ -192,6 +191,10 @@ const styles = StyleSheet.create({
fontSize: 22,
fontFamily: "Manrope_500Medium",
},
+ description:{
+ fontFamily: "Manrope_400Regular",
+ fontSize: 14,
+ }
});
export default MoveBrainDump;
diff --git a/components/pages/calendar/ManuallyAddEventModal.tsx b/components/pages/calendar/ManuallyAddEventModal.tsx
index ab2b19e..ed979f0 100644
--- a/components/pages/calendar/ManuallyAddEventModal.tsx
+++ b/components/pages/calendar/ManuallyAddEventModal.tsx
@@ -225,6 +225,7 @@ export const ManuallyAddEventModal = ({
{
setTitle(text);
}}
@@ -232,6 +233,7 @@ export const ManuallyAddEventModal = ({
style={{ fontFamily: "Manrope_500Medium", fontSize: 22 }}
paddingT-15
paddingL-30
+ returnKeyType="next"
/>
diff --git a/components/pages/grocery/CategoryDropdown.tsx b/components/pages/grocery/CategoryDropdown.tsx
index 7cb787a..a84eadb 100644
--- a/components/pages/grocery/CategoryDropdown.tsx
+++ b/components/pages/grocery/CategoryDropdown.tsx
@@ -23,7 +23,7 @@ const CategoryDropdown = (props: {
padding: 10,
}}
>
- {category}
+ {category}
))}
diff --git a/components/pages/grocery/EditGroceryItem.tsx b/components/pages/grocery/EditGroceryItem.tsx
index cfdb56d..73d994c 100644
--- a/components/pages/grocery/EditGroceryItem.tsx
+++ b/components/pages/grocery/EditGroceryItem.tsx
@@ -1,7 +1,8 @@
import {Text, View} from "react-native";
-import React, {useEffect, useRef} from "react";
+import React, {useEffect, useRef, useState} from "react";
import {TextField, TextFieldRef} from "react-native-ui-lib";
import {GroceryCategory, useGroceryContext,} from "@/contexts/GroceryContext";
+import CategoryDropdown from "./CategoryDropdown";
interface IEditGrocery {
id?: string;
@@ -17,6 +18,7 @@ interface IEditGrocery {
const EditGroceryItem = ({editGrocery}: { editGrocery: IEditGrocery }) => {
const {fuzzyMatchGroceryCategory} = useGroceryContext();
const inputRef = useRef(null);
+ const [category, setCategory] = useState(GroceryCategory.None);
useEffect(() => {
if (editGrocery.setCategory)
diff --git a/components/pages/main/SignUpPage.tsx b/components/pages/main/SignUpPage.tsx
index 5c843f9..e48e351 100644
--- a/components/pages/main/SignUpPage.tsx
+++ b/components/pages/main/SignUpPage.tsx
@@ -1,10 +1,11 @@
-import React, { useState } from "react";
+import React, { useRef, useState } from "react";
import {
Button,
ButtonSize,
Checkbox,
Text,
TextField,
+ TextFieldRef,
TouchableOpacity,
View,
} from "react-native-ui-lib";
@@ -13,7 +14,13 @@ import { ProfileType } from "@/contexts/AuthContext";
import { StyleSheet } from "react-native";
import { AntDesign } from "@expo/vector-icons";
-const SignUpPage = ({setTab}: { setTab: React.Dispatch> }) => {
+const SignUpPage = ({
+ setTab,
+}: {
+ setTab: React.Dispatch<
+ React.SetStateAction<"register" | "login" | "reset-password">
+ >;
+}) => {
const [email, setEmail] = useState("");
const [firstName, setFirstName] = useState("");
const [lastName, setLastName] = useState("");
@@ -24,6 +31,10 @@ const SignUpPage = ({setTab}: { setTab: React.Dispatch(false);
const { mutateAsync: signUp } = useSignUp();
+ const lnameRef = useRef(null);
+ const emailRef = useRef(null);
+ const passwordRef = useRef(null);
+
const handleSignUp = async () => {
await signUp({ email, password, firstName, lastName });
};
@@ -36,24 +47,34 @@ const SignUpPage = ({setTab}: { setTab: React.DispatchPlease enter your details.
{lnameRef.current?.focus()}}
+ blurOnSubmit={false}
/>
{emailRef.current?.focus()}}
+ blurOnSubmit={false}
/>
{passwordRef.current?.focus()}}
+ blurOnSubmit={false}
/>
{
const [selectedPage, setSelectedPage] = useState(0);
return (
-
- {selectedPage == 0 && (
-
-
- )}
- {selectedPage == pageIndex.calendar && (
-
- )}
- {selectedPage == pageIndex.chore && (
-
- )}
- {selectedPage == pageIndex.user && (
-
- )}
-
+
+ To-Do Reward Settings
+
+
+
+ }
+ onPress={() => setSelectedPage(pageIndex.chore)}
+ />
+
+
+
+ Cally Privacy Policy
+
+
+
+ }
+ />
+
+ )}
+ {selectedPage == pageIndex.calendar && (
+
+ )}
+ {selectedPage == pageIndex.chore && (
+
+ )}
+ {selectedPage == pageIndex.user && (
+
+ )}
+
);
};
@@ -92,14 +105,14 @@ export default SettingsPage;
const styles = StyleSheet.create({
mainBtn: {
- width: "100%",
+ width: 311,
justifyContent: "flex-start",
marginBottom: 20,
- height: 60,
+ height: 57.61,
},
- label:{
+ label: {
fontFamily: "Poppins_400Regular",
fontSize: 14.71,
- textAlignVertical: 'center'
- }
+ textAlignVertical: "center",
+ },
});
diff --git a/components/pages/settings/user_settings_views/MyGroup.tsx b/components/pages/settings/user_settings_views/MyGroup.tsx
index 20b202f..b815560 100644
--- a/components/pages/settings/user_settings_views/MyGroup.tsx
+++ b/components/pages/settings/user_settings_views/MyGroup.tsx
@@ -1,392 +1,505 @@
import {
- Avatar,
- Button,
- Card,
- Colors,
- Dialog,
- FloatingButton,
- PanningProvider,
- Picker,
- Text,
- TextField,
- TouchableOpacity,
- View,
+ Avatar,
+ Button,
+ Card,
+ Colors,
+ Dialog,
+ FloatingButton,
+ PanningProvider,
+ Picker,
+ Text,
+ TextField,
+ TextFieldRef,
+ TouchableOpacity,
+ View,
} from "react-native-ui-lib";
-import React, {useState} from "react";
-import {ScrollView, StyleSheet} from "react-native";
-import {PickerSingleValue} from "react-native-ui-lib/src/components/picker/types";
-import {useCreateSubUser} from "@/hooks/firebase/useCreateSubUser";
-import {ProfileType} from "@/contexts/AuthContext";
-import {useGetFamilyMembers} from "@/hooks/firebase/useGetFamilyMembers";
+import React, { useEffect, useRef, useState } from "react";
+import { Dimensions, ScrollView, StyleSheet } from "react-native";
+import { PickerSingleValue } from "react-native-ui-lib/src/components/picker/types";
+import { useCreateSubUser } from "@/hooks/firebase/useCreateSubUser";
+import { ProfileType } from "@/contexts/AuthContext";
+import { useGetFamilyMembers } from "@/hooks/firebase/useGetFamilyMembers";
import UserMenu from "@/components/pages/settings/user_settings_views/UserMenu";
-import {uuidv4} from "@firebase/util";
+import { uuidv4 } from "@firebase/util";
+import QRIcon from "@/assets/svgs/QRIcon";
+import EmailIcon from "@/assets/svgs/EmailIcon";
+import CircledXIcon from "@/assets/svgs/CircledXIcon";
+import ProfileIcon from "@/assets/svgs/ProfileIcon";
+import NavToDosIcon from "@/assets/svgs/NavToDosIcon";
const MyGroup = () => {
- const [showAddUserDialog, setShowAddUserDialog] = useState(false);
- const [showNewUserInfoDialog, setShowNewUserInfoDialog] = useState(false);
- const [selectedStatus, setSelectedStatus] = useState<
- string | PickerSingleValue
- >(ProfileType.CHILD);
- const [firstName, setFirstName] = useState("");
- const [lastName, setLastName] = useState("");
- const [email, setEmail] = useState("");
+ const [showAddUserDialog, setShowAddUserDialog] = useState(false);
+ const [showNewUserInfoDialog, setShowNewUserInfoDialog] = useState(false);
+ const [selectedStatus, setSelectedStatus] = useState<
+ string | PickerSingleValue
+ >(ProfileType.CHILD);
+ const [firstName, setFirstName] = useState("");
+ const [lastName, setLastName] = useState("");
+ const [email, setEmail] = useState("");
- const [showQRCodeDialog, setShowQRCodeDialog] = useState("");
+ const lNameRef = useRef(null);
+ const emailRef = useRef(null);
- const {mutateAsync: createSubUser, isLoading, isError} = useCreateSubUser();
- const {data: familyMembers} = useGetFamilyMembers(true);
+ const [showQRCodeDialog, setShowQRCodeDialog] = useState("");
- const parents =
- familyMembers?.filter((x) => x.userType === ProfileType.PARENT) ?? [];
- const children =
- familyMembers?.filter((x) => x.userType === ProfileType.CHILD) ?? [];
- const caregivers =
- familyMembers?.filter((x) => x.userType === ProfileType.CAREGIVER) ?? [];
- const familyDevices =
- familyMembers?.filter((x) => x.userType === ProfileType.FAMILY_DEVICE) ?? [];
+ const { mutateAsync: createSubUser, isLoading, isError } = useCreateSubUser();
+ const { data: familyMembers } = useGetFamilyMembers(true);
- const handleCreateSubUser = async () => {
- if (!firstName || (selectedStatus !== ProfileType.FAMILY_DEVICE && !lastName)) {
- console.error("First name and last name are required");
- return;
- }
+ const parents =
+ familyMembers?.filter((x) => x.userType === ProfileType.PARENT) ?? [];
+ const children =
+ familyMembers?.filter((x) => x.userType === ProfileType.CHILD) ?? [];
+ const caregivers =
+ familyMembers?.filter((x) => x.userType === ProfileType.CAREGIVER) ?? [];
+ const familyDevices =
+ familyMembers?.filter((x) => x.userType === ProfileType.FAMILY_DEVICE) ??
+ [];
- if (selectedStatus !== ProfileType.FAMILY_DEVICE && !email) {
- console.error("Email is required for non-family device users");
- return;
- }
+ const handleCreateSubUser = async () => {
+ if (
+ !firstName ||
+ (selectedStatus !== ProfileType.FAMILY_DEVICE && !lastName)
+ ) {
+ console.error("First name and last name are required");
+ return;
+ }
- if (email && !email.includes("@")) {
- console.error("Invalid email address");
- return;
- }
+ if (selectedStatus !== ProfileType.FAMILY_DEVICE && !email) {
+ console.error("Email is required for non-family device users");
+ return;
+ }
- const res = await createSubUser({
- firstName,
- lastName: selectedStatus === ProfileType.FAMILY_DEVICE ? "" : lastName,
- email: email || `placeholder_${uuidv4().split("-")[0]}@family.device`,
- password: uuidv4(),
- userType: selectedStatus as ProfileType,
- });
- console.log(res)
+ if (email && !email.includes("@")) {
+ console.error("Invalid email address");
+ return;
+ }
- if (!isError) {
- setShowNewUserInfoDialog(false);
+ const res = await createSubUser({
+ firstName,
+ lastName: selectedStatus === ProfileType.FAMILY_DEVICE ? "" : lastName,
+ email: email || `placeholder_${uuidv4().split("-")[0]}@family.device`,
+ password: uuidv4(),
+ userType: selectedStatus as ProfileType,
+ });
+ console.log(res);
- if(res?.data?.userId) {
- setTimeout(() => {
- setShowQRCodeDialog(res.data.userId)
- }, 500)
- }
- }
+ if (!isError) {
+ setShowNewUserInfoDialog(false);
+ if (res?.data?.userId) {
+ setTimeout(() => {
+ setShowQRCodeDialog(res.data.userId);
+ }, 500);
+ }
+ }
+ };
- };
+ useEffect(() => {
+ setFirstName("");
+ setLastName("");
+ setEmail("");
+ }, [])
+
- return (
-
-
-
- {!parents.length && !children.length && !caregivers.length && (
-
- {isLoading ? "Loading...." : "No user devices added"}
-
- )}
+ return (
+
+
+
+ {!parents.length && !children.length && !caregivers.length && (
+
+ {isLoading ? "Loading...." : "No user devices added"}
+
+ )}
- {(!!parents.length || !!children.length) && (
- <>
-
- Family
-
- {[...parents, ...children]?.map((member, index) => (
-
-
-
-
- {member.firstName} {member.lastName}
-
-
- {member.userType === ProfileType.PARENT
- ? "Admin (You)"
- : "Child"}
-
-
-
-
-
- setShowQRCodeDialog("")} showQRCodeDialog={showQRCodeDialog === member?.uid} userId={member?.uid!}/>
-
- ))}
- >
- )}
-
- {!!caregivers.length && (
- <>
-
- Caregivers
-
- {caregivers?.map((member) => (
-
-
-
-
- {member.firstName} {member.lastName}
-
-
- Caregiver
-
-
-
- setShowQRCodeDialog("")} showQRCodeDialog={showQRCodeDialog === member?.uid} userId={member?.uid!}/>
-
- ))}
- >
- )}
-
- {!!familyDevices.length && (
- <>
-
- Family Devices
-
- {familyDevices?.map((member, index) => (
-
-
-
-
- {member.firstName}
-
-
- Family Device
-
-
-
- setShowQRCodeDialog("")} showQRCodeDialog={showQRCodeDialog === member?.uid} userId={member?.uid!}/>
-
- ))}
- >
- )}
-
-
-
- setShowAddUserDialog(true),
- }}
- />
-
-
-
-
-
- );
+ ))}
+ >
+ )}
+
+ {!!caregivers.length && (
+ <>
+
+ Caregivers
+
+ {caregivers?.map((member) => (
+
+
+
+
+ {member.firstName} {member.lastName}
+
+
+ Caregiver
+
+
+
+ setShowQRCodeDialog("")}
+ showQRCodeDialog={showQRCodeDialog === member?.uid}
+ userId={member?.uid!}
+ />
+
+ ))}
+ >
+ )}
+
+ {!!familyDevices.length && (
+ <>
+
+ Family Devices
+
+ {familyDevices?.map((member, index) => (
+
+
+
+ {member.firstName}
+
+ Family Device
+
+
+
+ setShowQRCodeDialog("")}
+ showQRCodeDialog={showQRCodeDialog === member?.uid}
+ userId={member?.uid!}
+ />
+
+ ))}
+ >
+ )}
+
+
+
+ setShowAddUserDialog(true),
+ style: styles.bottomButton,
+ }}
+ />
+
+
+
+
+
+ );
};
const styles = StyleSheet.create({
- card: {
- marginVertical: 15,
- backgroundColor: "white",
- width: "100%",
- borderRadius: 15,
- padding: 20,
- },
- familyCard: {
- marginBottom: 10,
- borderRadius: 10,
- backgroundColor: Colors.white,
- width: "100%",
- },
- inputField: {
- borderRadius: 50,
- paddingVertical: 12,
- paddingHorizontal: 16,
- backgroundColor: Colors.grey80,
- marginBottom: 16,
- borderColor: Colors.grey50,
- borderWidth: 1,
- height: 40,
- },
- picker: {
- borderRadius: 50,
- paddingVertical: 12,
- paddingHorizontal: 16,
- backgroundColor: Colors.grey80,
- marginBottom: 16,
- borderColor: Colors.grey50,
- borderWidth: 1,
- marginTop: -20,
- height: 40,
- },
- label: {
- marginBottom: 5,
- fontSize: 12,
- color: Colors.grey40,
- },
- dialogCard: {
- borderRadius: 10,
- gap: 10,
- },
- subTit: {
- fontFamily: "Manrope_500Medium",
- fontSize: 15,
- },
+ dialogBtn: {
+ height: 47,
+ width: 279,
+ },
+ dialogTitle: { fontFamily: "Manrope_600SemiBold", fontSize: 22 },
+ dialogBackBtn: {
+ fontFamily: "PlusJakartaSans_500Medium",
+ fontSize: 15,
+ color: "#a7a7a7",
+ },
+ card: {
+ marginVertical: 15,
+ backgroundColor: "white",
+ width: "100%",
+ borderRadius: 15,
+ padding: 20,
+ },
+ bottomButton: {
+ position: "absolute",
+ bottom: 80,
+ width: "100%",
+ },
+ familyCard: {
+ marginBottom: 10,
+ borderRadius: 10,
+ backgroundColor: Colors.white,
+ width: "100%",
+ },
+ inputField: {
+ fontFamily: "PlusJakartaSans_500Medium",
+ fontSize: 13,
+ color: "#565656",
+ borderRadius: 50,
+ paddingVertical: 12,
+ paddingHorizontal: 16,
+ backgroundColor: Colors.grey80,
+ marginBottom: 16,
+ borderColor: Colors.grey50,
+ borderWidth: 1,
+ height: 40,
+ },
+ picker: {
+ borderRadius: 50,
+ paddingVertical: 12,
+ paddingHorizontal: 16,
+ backgroundColor: Colors.grey80,
+ marginBottom: 16,
+ borderColor: Colors.grey50,
+ borderWidth: 1,
+ marginTop: -20,
+ height: 40,
+ },
+ label: {
+ marginBottom: 5,
+ fontSize: 12,
+ color: Colors.grey40,
+ },
+ dialogCard: {
+ borderRadius: 10,
+ gap: 10,
+ },
+ subTit: {
+ fontFamily: "Manrope_500Medium",
+ fontSize: 15,
+ },
+ dialogBtnLbl: {
+ fontFamily: "PlusJakartaSans_500Medium",
+ fontSize: 15,
+ color: "white",
+ },
+ divider: { height: 0.7, backgroundColor: "#e6e6e6", width: "100%" },
+ jakarta12: {
+ fontFamily: "PlusJakartaSans_500Medium",
+ fontSize: 12,
+ color: "#a1a1a1",
+ },
+ jakarta13: {
+ fontFamily: "PlusJakartaSans_500Medium",
+ fontSize: 13,
+ },
});
export default MyGroup;
diff --git a/components/pages/settings/user_settings_views/UserMenu.tsx b/components/pages/settings/user_settings_views/UserMenu.tsx
index ed01179..74f4bfc 100644
--- a/components/pages/settings/user_settings_views/UserMenu.tsx
+++ b/components/pages/settings/user_settings_views/UserMenu.tsx
@@ -30,7 +30,7 @@ const UserMenu = ({
customContent={
- Show Login QR Code
+ Show Login QR Code
}
diff --git a/components/pages/todos/AddChoreDialog.tsx b/components/pages/todos/AddChoreDialog.tsx
index 8dc80c1..c8f061c 100644
--- a/components/pages/todos/AddChoreDialog.tsx
+++ b/components/pages/todos/AddChoreDialog.tsx
@@ -1,5 +1,5 @@
import { View, Text, Button, Switch } from "react-native-ui-lib";
-import React, { useState } from "react";
+import React, { useRef, useState } from "react";
import PointsSlider from "@/components/shared/PointsSlider";
import { repeatOptions, useToDosContext } from "@/contexts/ToDosContext";
import { Feather, AntDesign, Ionicons } from "@expo/vector-icons";
@@ -14,6 +14,7 @@ import { PanningDirectionsEnum } from "react-native-ui-lib/src/incubator/panView
import { Dimensions, StyleSheet } from "react-native";
import DropModalIcon from "@/assets/svgs/DropModalIcon";
import { IToDo } from "@/hooks/firebase/types/todoData";
+import AssigneesDisplay from "@/components/shared/AssigneesDisplay";
interface IAddChoreDialog {
isVisible: boolean;
@@ -111,6 +112,7 @@ const AddChoreDialog = (addChoreDialogProps: IAddChoreDialog) => {
{
setTodo((oldValue: IToDo) => ({ ...oldValue, title: text }));
@@ -197,25 +199,8 @@ const AddChoreDialog = (addChoreDialogProps: IAddChoreDialog) => {
label="Assign"
/>
-
-
-
+
+
Take Turns