mirror of
https://github.com/urosran/cally.git
synced 2025-07-16 01:56:16 +00:00
notes, tablet sort, grocery list and other fixes
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
import React, {useEffect} from "react";
|
||||
import React, {useEffect, useMemo} from "react";
|
||||
import {Text, View} from "react-native-ui-lib";
|
||||
import * as ScreenOrientation from "expo-screen-orientation";
|
||||
import TabletContainer from "../tablet_components/TabletContainer";
|
||||
@ -7,10 +7,29 @@ import { useGetFamilyMembers } from "@/hooks/firebase/useGetFamilyMembers";
|
||||
import { ImageBackground, StyleSheet } from "react-native";
|
||||
import { colorMap } from "@/constants/colorMap";
|
||||
import { ScrollView } from "react-native-gesture-handler";
|
||||
import { ProfileType } from "@/contexts/AuthContext";
|
||||
import { ProfileType, useAuthContext } from "@/contexts/AuthContext";
|
||||
|
||||
const TabletChoresPage = () => {
|
||||
const {data: users} = useGetFamilyMembers();
|
||||
const { user: currentUser } = useAuthContext();
|
||||
|
||||
const sortedUsers = useMemo(() => {
|
||||
return users
|
||||
?.filter(member => member.userType !== ProfileType.FAMILY_DEVICE)
|
||||
.sort((a, b) => {
|
||||
if (a.uid === currentUser?.uid) return -1;
|
||||
if (b.uid === currentUser?.uid) return 1;
|
||||
|
||||
const typePriority = {
|
||||
[ProfileType.PARENT]: 0,
|
||||
[ProfileType.CHILD]: 1,
|
||||
[ProfileType.CAREGIVER]: 2
|
||||
};
|
||||
|
||||
return typePriority[a.userType] - typePriority[b.userType];
|
||||
});
|
||||
}, [users, currentUser]);
|
||||
|
||||
// Function to lock the screen orientation to landscape
|
||||
const lockScreenOrientation = async () => {
|
||||
await ScreenOrientation.lockAsync(
|
||||
@ -27,11 +46,16 @@ const TabletChoresPage = () => {
|
||||
};
|
||||
}, []);
|
||||
|
||||
const capitalizeFirstLetter = (str: string) => {
|
||||
if (!str) return "";
|
||||
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
|
||||
};
|
||||
|
||||
return (
|
||||
<TabletContainer>
|
||||
<ScrollView horizontal>
|
||||
<View row gap-25 padding-25>
|
||||
{users
|
||||
{sortedUsers
|
||||
?.filter((member) => member.userType !== ProfileType.FAMILY_DEVICE)
|
||||
.map((user, index) => (
|
||||
<View key={index}>
|
||||
@ -66,7 +90,7 @@ const TabletChoresPage = () => {
|
||||
{user.firstName}
|
||||
</Text>
|
||||
<Text style={[styles.name, { color: "#9b9b9b" }]} marginL-5>
|
||||
({user.userType})
|
||||
({capitalizeFirstLetter(user.userType)})
|
||||
</Text>
|
||||
</View>
|
||||
<SingleUserChoreList user={user} />
|
||||
|
@ -1,11 +1,13 @@
|
||||
import { View, Text } from "react-native-ui-lib";
|
||||
import React, { useEffect } from "react";
|
||||
import React, { useEffect, useMemo } from "react";
|
||||
import { useGetFamilyMembers } from "@/hooks/firebase/useGetFamilyMembers";
|
||||
import { ImageBackground, StyleSheet } from "react-native";
|
||||
import { colorMap } from "@/constants/colorMap";
|
||||
import { ProfileType } from "@/contexts/AuthContext";
|
||||
import { ProfileType, useAuthContext } from "@/contexts/AuthContext";
|
||||
import { ScrollView } from "react-native-gesture-handler";
|
||||
|
||||
const UsersList = () => {
|
||||
const { user: currentUser } = useAuthContext();
|
||||
const { data: familyMembers, refetch: refetchFamilyMembers } =
|
||||
useGetFamilyMembers();
|
||||
|
||||
@ -13,17 +15,34 @@ const UsersList = () => {
|
||||
refetchFamilyMembers();
|
||||
}, []);
|
||||
|
||||
const sortedMembers = useMemo(() => {
|
||||
return familyMembers
|
||||
?.filter((member) => member.userType !== ProfileType.FAMILY_DEVICE)
|
||||
.sort((a, b) => {
|
||||
// Current user first
|
||||
if (a.uid === currentUser?.uid) return -1;
|
||||
if (b.uid === currentUser?.uid) return 1;
|
||||
|
||||
// Then sort by user type priority
|
||||
const typePriority = {
|
||||
[ProfileType.PARENT]: 0,
|
||||
[ProfileType.CHILD]: 1,
|
||||
[ProfileType.CAREGIVER]: 2,
|
||||
};
|
||||
|
||||
return typePriority[a.userType] - typePriority[b.userType];
|
||||
});
|
||||
}, [familyMembers, currentUser]);
|
||||
|
||||
const capitalizeFirstLetter = (str: string) => {
|
||||
if (!str) return "";
|
||||
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
|
||||
};
|
||||
|
||||
return (
|
||||
<View centerH paddingT-10>
|
||||
{familyMembers
|
||||
?.filter((member) => member.userType !== ProfileType.FAMILY_DEVICE)
|
||||
.map((member, index) => (
|
||||
<>
|
||||
<View centerH paddingT-10 marginB-70>
|
||||
{sortedMembers?.map((member, index) => (
|
||||
<React.Fragment key={member.uid}>
|
||||
{member.pfp ? (
|
||||
<ImageBackground
|
||||
key={index}
|
||||
@ -38,19 +57,18 @@ const UsersList = () => {
|
||||
style={styles.pfp}
|
||||
center
|
||||
backgroundColor={member.eventColor || colorMap.teal}
|
||||
children={
|
||||
<Text color="white">
|
||||
{member.firstName.at(0)}
|
||||
{member.lastName.at(0)}
|
||||
</Text>
|
||||
}
|
||||
/>
|
||||
>
|
||||
<Text color="white">
|
||||
{member.firstName.at(0)}
|
||||
{member.lastName.at(0)}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
<Text style={styles.fName}>{member.firstName}</Text>
|
||||
<Text style={styles.role}>
|
||||
{capitalizeFirstLetter(member.userType)}
|
||||
</Text>
|
||||
</>
|
||||
</React.Fragment>
|
||||
))}
|
||||
</View>
|
||||
);
|
||||
|
@ -3,11 +3,11 @@ import React from "react";
|
||||
import { useBrainDumpContext } from "@/contexts/DumpContext";
|
||||
import { FlatList } from "react-native";
|
||||
import BrainDumpItem from "./DumpItem";
|
||||
|
||||
import { StyleSheet } from "react-native";
|
||||
const DumpList = (props: { searchText: string }) => {
|
||||
const { brainDumps } = useBrainDumpContext();
|
||||
|
||||
const filteredBrainDumps =
|
||||
const sortedDumps =
|
||||
props.searchText.trim() === ""
|
||||
? brainDumps
|
||||
: brainDumps.filter(
|
||||
@ -18,18 +18,21 @@ const DumpList = (props: { searchText: string }) => {
|
||||
.includes(props.searchText.toLowerCase())
|
||||
);
|
||||
|
||||
return (
|
||||
<View marginB-70>
|
||||
<FlatList
|
||||
style={{ zIndex: -1 }}
|
||||
data={filteredBrainDumps}
|
||||
keyExtractor={(item) => item.title}
|
||||
renderItem={({ item }) => (
|
||||
<BrainDumpItem key={item.title} item={item} />
|
||||
)}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<View marginB-70>
|
||||
{brainDumps?.length ? <FlatList
|
||||
style={{ zIndex: -1 }}
|
||||
data={sortedDumps}
|
||||
keyExtractor={(item) => item.title}
|
||||
renderItem={({ item }) => (
|
||||
<BrainDumpItem key={item.title} item={item} />
|
||||
)}
|
||||
/> : <Text marginT-20 center style={styles.alert}>You have no notes</Text>}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
alert: {fontFamily: "PlusJakartaSans_300Light", fontSize: 20}
|
||||
})
|
||||
export default DumpList;
|
||||
|
@ -122,16 +122,14 @@ const GroceryList = ({onInputFocus}: {onInputFocus: (y: number) => void}) => {
|
||||
{/* Pending Approval Section */}
|
||||
<View row spread marginT-40 marginB-10 centerV>
|
||||
<View row centerV>
|
||||
<TouchableOpacity row centerV onPress={() => {setPendingVisible(!pendingVisible)}}>
|
||||
<Text style={styles.subHeader}>Pending Approval</Text>
|
||||
{pendingVisible && (
|
||||
<AntDesign
|
||||
name="down"
|
||||
size={17}
|
||||
style={styles.dropIcon}
|
||||
color="#9f9f9f"
|
||||
onPress={() => {
|
||||
setPendingVisible(false);
|
||||
}}
|
||||
name="down"
|
||||
size={17}
|
||||
style={styles.dropIcon}
|
||||
color="#9f9f9f"
|
||||
/>
|
||||
)}
|
||||
{!pendingVisible && (
|
||||
@ -140,11 +138,9 @@ const GroceryList = ({onInputFocus}: {onInputFocus: (y: number) => void}) => {
|
||||
size={15}
|
||||
style={styles.dropIcon}
|
||||
color="#9f9f9f"
|
||||
onPress={() => {
|
||||
setPendingVisible(true);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View
|
||||
centerV
|
||||
@ -183,6 +179,7 @@ const GroceryList = ({onInputFocus}: {onInputFocus: (y: number) => void}) => {
|
||||
{/* Approved Section */}
|
||||
<View row spread marginT-40 marginB-0 centerV>
|
||||
<View row centerV>
|
||||
<TouchableOpacity row centerV onPress={() => {setApprovedVisible(!approvedVisible)}}>
|
||||
<Text style={styles.subHeader}>Shopping List</Text>
|
||||
{approvedVisible && (
|
||||
<AntDesign
|
||||
@ -190,9 +187,6 @@ const GroceryList = ({onInputFocus}: {onInputFocus: (y: number) => void}) => {
|
||||
size={17}
|
||||
style={styles.dropIcon}
|
||||
color="#9f9f9f"
|
||||
onPress={() => {
|
||||
setApprovedVisible(false);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{!approvedVisible && (
|
||||
@ -201,11 +195,9 @@ const GroceryList = ({onInputFocus}: {onInputFocus: (y: number) => void}) => {
|
||||
size={15}
|
||||
style={styles.dropIcon}
|
||||
color="#9f9f9f"
|
||||
onPress={() => {
|
||||
setApprovedVisible(true);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View
|
||||
centerV
|
||||
|
@ -32,7 +32,7 @@ const AssigneesDisplay = ({selectedAttendees, setSelectedAttendees}: {
|
||||
children={<RemoveAssigneeBtn/>}
|
||||
/>
|
||||
) : (
|
||||
<View style={[styles.initialsCircle, {borderWidth: 2, borderColor: member.eventColor || 'transparent'}]}>
|
||||
<View style={[styles.initialsCircle, {borderWidth: 2, borderColor: member.eventColor || 'transparent', backgroundColor: member.eventColor || 'gray'}]}>
|
||||
<Text style={styles.initialsText}>
|
||||
{getInitials(member.firstName, member.lastName)}
|
||||
</Text>
|
||||
|
@ -26,7 +26,7 @@ const BrainDumpContext = createContext<IBrainDumpContext | undefined>(
|
||||
export const BrainDumpProvider: React.FC<{ children: React.ReactNode }> = ({
|
||||
children,
|
||||
}) => {
|
||||
const { data: brainDumps } = useGetNotes();
|
||||
const { data: brainDumps, refetch } = useGetNotes();
|
||||
const { mutate: deleteNote } = useDeleteNote();
|
||||
const { mutateAsync: createBrainDump } = useCreateNote();
|
||||
const { mutateAsync: updateNoteMutate } = useUpdateNote();
|
||||
|
@ -5,7 +5,7 @@ import { IFeedback } from "@/contexts/FeedbackContext";
|
||||
import { IBrainDump } from "@/contexts/DumpContext";
|
||||
|
||||
export const useCreateNote = () => {
|
||||
const { user: currentUser, profileData } = useAuthContext();
|
||||
const { user: currentUser } = useAuthContext();
|
||||
const queryClients = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
|
@ -13,6 +13,7 @@ export const useGetNotes = () => {
|
||||
const snapshot = await firestore()
|
||||
.collection("BrainDumps")
|
||||
.where("creatorId", "==", currentUser?.uid)
|
||||
.orderBy("updatedAt", "desc")
|
||||
.get();
|
||||
|
||||
return snapshot.docs.map((doc) => ({
|
||||
|
Reference in New Issue
Block a user