mirror of
https://github.com/urosran/cally.git
synced 2025-07-16 18:16:17 +00:00
todo filtering, nanny shopping
This commit is contained in:
@ -111,18 +111,21 @@ export default function TabLayout() {
|
||||
const showViewSwitch = ["calendar", "todos", "index"].includes(
|
||||
route.name
|
||||
);
|
||||
const isCalendarPage = ["calendar", "index"].includes(route.name);
|
||||
|
||||
if (Device.deviceType !== DeviceType.TABLET || !showViewSwitch) {
|
||||
return (
|
||||
return isCalendarPage ? (
|
||||
<View marginR-16>
|
||||
<RefreshButton onRefresh={onRefresh} isSyncing={isSyncing} />
|
||||
</View>
|
||||
);
|
||||
) : null;
|
||||
}
|
||||
|
||||
return (
|
||||
<View marginR-16 row>
|
||||
<RefreshButton onRefresh={onRefresh} isSyncing={isSyncing} />
|
||||
<View marginR-16 row centerV>
|
||||
{isCalendarPage && (
|
||||
<View marginR-16><RefreshButton onRefresh={onRefresh} isSyncing={isSyncing} /></View>
|
||||
)}
|
||||
<MemoizedViewSwitch navigation={navigation} />
|
||||
</View>
|
||||
);
|
||||
|
@ -15,7 +15,12 @@ import { UserProfile } from "@/hooks/firebase/types/profileTypes";
|
||||
import { ScrollView } from "react-native-gesture-handler";
|
||||
|
||||
const groupToDosByDate = (toDos: IToDo[]) => {
|
||||
let sortedTodos = toDos.sort((a, b) => a.date - b.date);
|
||||
let sortedTodos = toDos.sort((a, b) => {
|
||||
const dateA = a.date === null ? new Date() : a.date;
|
||||
const dateB = b.date === null ? new Date() : b.date;
|
||||
return dateA - dateB;
|
||||
});
|
||||
|
||||
return sortedTodos.reduce(
|
||||
(groups, toDo) => {
|
||||
let dateKey;
|
||||
@ -34,9 +39,7 @@ const groupToDosByDate = (toDos: IToDo[]) => {
|
||||
});
|
||||
};
|
||||
|
||||
if (toDo.date === null) {
|
||||
dateKey = "No Date";
|
||||
} else if (isToday(toDo.date)) {
|
||||
if (toDo.date === null || isToday(toDo.date)) {
|
||||
dateKey = "Today";
|
||||
} else if (isTomorrow(toDo.date)) {
|
||||
dateKey = "Tomorrow";
|
||||
@ -228,42 +231,47 @@ const SingleUserChoreList = ({ user }: { user: UserProfile }) => {
|
||||
|
||||
return (
|
||||
<View
|
||||
marginB-402
|
||||
marginT-10
|
||||
paddingH-10
|
||||
backgroundColor="#f9f8f7"
|
||||
style={{ minHeight: 800, borderRadius: 9.11 }}
|
||||
style={{
|
||||
minHeight: 600,
|
||||
maxHeight: 600,
|
||||
borderRadius: 9.11,
|
||||
overflow: "hidden",
|
||||
}}
|
||||
width={355}
|
||||
>
|
||||
<ScrollView>
|
||||
{noDateToDos.length > 0 && (
|
||||
<View key="No Date">
|
||||
<View row spread paddingH-19 marginB-12>
|
||||
<Text
|
||||
text70
|
||||
style={{
|
||||
fontWeight: "bold",
|
||||
}}
|
||||
>
|
||||
Unscheduled
|
||||
</Text>
|
||||
<AntDesign
|
||||
name={expandNoDate ? "caretdown" : "caretright"}
|
||||
size={24}
|
||||
color="#fd1575"
|
||||
onPress={() => {
|
||||
setExpandNoDate(!expandNoDate);
|
||||
}}
|
||||
/>
|
||||
<ScrollView showsVerticalScrollIndicator={false}>
|
||||
<View paddingH-10 paddingB-90>
|
||||
{noDateToDos.length > 0 && (
|
||||
<View key="No Date">
|
||||
<View row spread paddingH-19 marginB-12>
|
||||
<Text
|
||||
text70
|
||||
style={{
|
||||
fontWeight: "bold",
|
||||
}}
|
||||
>
|
||||
Unscheduled
|
||||
</Text>
|
||||
<AntDesign
|
||||
name={expandNoDate ? "caretdown" : "caretright"}
|
||||
size={24}
|
||||
color="#fd1575"
|
||||
onPress={() => {
|
||||
setExpandNoDate(!expandNoDate);
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
{expandNoDate &&
|
||||
noDateToDos
|
||||
.sort((a, b) => Number(a.done) - Number(b.done))
|
||||
.map((item) => <ToDoItem key={item.id} item={item} />)}
|
||||
</View>
|
||||
{expandNoDate &&
|
||||
noDateToDos
|
||||
.sort((a, b) => Number(a.done) - Number(b.done))
|
||||
.map((item) => <ToDoItem key={item.id} item={item} />)}
|
||||
</View>
|
||||
)}
|
||||
)}
|
||||
|
||||
{datedToDos.map(renderTodoGroup)}
|
||||
{datedToDos.map(renderTodoGroup)}
|
||||
</View>
|
||||
</ScrollView>
|
||||
</View>
|
||||
);
|
||||
|
@ -8,6 +8,7 @@ import { ImageBackground, StyleSheet } from "react-native";
|
||||
import { colorMap } from "@/constants/colorMap";
|
||||
import { ScrollView } from "react-native-gesture-handler";
|
||||
import { ProfileType, useAuthContext } from "@/contexts/AuthContext";
|
||||
import AddChore from "../../todos/AddChore";
|
||||
|
||||
const TabletChoresPage = () => {
|
||||
const {data: users} = useGetFamilyMembers();
|
||||
@ -98,6 +99,9 @@ const TabletChoresPage = () => {
|
||||
))}
|
||||
</View>
|
||||
</ScrollView>
|
||||
<View style={styles.addBtn}>
|
||||
<AddChore />
|
||||
</View>
|
||||
</TabletContainer>
|
||||
);
|
||||
};
|
||||
@ -113,6 +117,11 @@ const styles = StyleSheet.create({
|
||||
fontSize: 22.43,
|
||||
color: "#2c2c2c",
|
||||
},
|
||||
addBtn: {
|
||||
position: 'absolute',
|
||||
bottom: 50,
|
||||
right: 220
|
||||
}
|
||||
});
|
||||
|
||||
export default TabletChoresPage;
|
||||
|
@ -25,6 +25,7 @@ const GroceryItem = ({
|
||||
const { profileData } = useAuthContext();
|
||||
const { data: creator } = useGetUserById(item.creatorId);
|
||||
const isParent = profileData?.userType === ProfileType.PARENT;
|
||||
const isCaregiver = profileData?.userType === ProfileType.CAREGIVER;
|
||||
|
||||
const [openFreqEdit, setOpenFreqEdit] = useState<boolean>(false);
|
||||
const [isEditingTitle, setIsEditingTitle] = useState<boolean>(false);
|
||||
@ -36,7 +37,7 @@ const GroceryItem = ({
|
||||
const closeEdit = () => setIsEditingTitle(false);
|
||||
|
||||
const getInitials = (firstName: string, lastName: string) => {
|
||||
return `${firstName.charAt(0)}${lastName.charAt(0)}`;
|
||||
return `${firstName.charAt(0).toUpperCase()}${lastName.charAt(0).toUpperCase()}`;
|
||||
};
|
||||
|
||||
return (
|
||||
@ -81,7 +82,7 @@ const GroceryItem = ({
|
||||
/>
|
||||
) : (
|
||||
<View flex>
|
||||
{isParent ? (
|
||||
{(isParent || isCaregiver) && !item.bought ? (
|
||||
<TouchableOpacity onPress={() => setIsEditingTitle(true)}>
|
||||
<Text
|
||||
text70T
|
||||
@ -98,7 +99,7 @@ const GroceryItem = ({
|
||||
) : (
|
||||
<Text
|
||||
text70T
|
||||
style={[styles.title, { color: item.bought ? "red" : "black" }]}
|
||||
style={[styles.title, { textDecorationLine: item.bought ? "line-through" : "none", }]}
|
||||
>
|
||||
{item.title}
|
||||
</Text>
|
||||
@ -108,7 +109,7 @@ const GroceryItem = ({
|
||||
|
||||
{!item.approved ? (
|
||||
<View row centerV>
|
||||
{isParent && (
|
||||
{isParent || isCaregiver && (
|
||||
<>
|
||||
<AntDesign
|
||||
name="check"
|
||||
@ -132,7 +133,7 @@ const GroceryItem = ({
|
||||
</View>
|
||||
) : (
|
||||
!isEditingTitle &&
|
||||
isParent && (
|
||||
(isParent || isCaregiver) && (
|
||||
<Checkbox
|
||||
value={item.bought}
|
||||
containerStyle={[styles.checkbox, { borderRadius: 50 }]}
|
||||
@ -180,7 +181,7 @@ const GroceryItem = ({
|
||||
width: 24.64,
|
||||
aspectRatio: 1,
|
||||
marginRight: 8,
|
||||
backgroundColor: "#ccc",
|
||||
backgroundColor: creator?.eventColor || "gray",
|
||||
borderRadius: 100,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
|
@ -62,7 +62,7 @@ const GroceryList = ({onInputFocus}: {onInputFocus: (y: number) => void}) => {
|
||||
id: "",
|
||||
title: title,
|
||||
category: category,
|
||||
approved: profileData?.userType === ProfileType.PARENT,
|
||||
approved: profileData?.userType === ProfileType.PARENT || profileData?.userType === ProfileType.CAREGIVER,
|
||||
recurring: false,
|
||||
frequency: GroceryFrequency.Never,
|
||||
bought: false,
|
||||
|
@ -138,6 +138,7 @@ const AddChoreDialog = (addChoreDialogProps: IAddChoreDialog) => {
|
||||
padding: 0,
|
||||
paddingTop: 4,
|
||||
margin: 0,
|
||||
maxWidth: 600
|
||||
}}
|
||||
visible={addChoreDialogProps.isVisible}
|
||||
>
|
||||
|
@ -17,7 +17,12 @@ const FILTER_OPTIONS = {
|
||||
};
|
||||
|
||||
const groupToDosByDate = (toDos: IToDo[]) => {
|
||||
let sortedTodos = toDos.sort((a, b) => a.date - b.date);
|
||||
let sortedTodos = toDos.sort((a, b) => {
|
||||
const dateA = a.date === null ? new Date() : a.date;
|
||||
const dateB = b.date === null ? new Date() : b.date;
|
||||
return dateA - dateB;
|
||||
});
|
||||
|
||||
return sortedTodos.reduce(
|
||||
(groups, toDo) => {
|
||||
let dateKey;
|
||||
@ -36,9 +41,15 @@ const groupToDosByDate = (toDos: IToDo[]) => {
|
||||
});
|
||||
};
|
||||
|
||||
if (toDo.date === null) {
|
||||
dateKey = "No Date";
|
||||
} else if (isToday(toDo.date)) {
|
||||
const isOverdue = (date: Date) => {
|
||||
const today = new Date();
|
||||
today.setHours(0, 0, 0, 0);
|
||||
return date < today;
|
||||
};
|
||||
|
||||
if (isOverdue(toDo.date) && !toDo.done) {
|
||||
dateKey = "Overdue";
|
||||
} else if (toDo.date === null || isToday(toDo.date)) {
|
||||
dateKey = "Today";
|
||||
} else if (isTomorrow(toDo.date)) {
|
||||
dateKey = "Tomorrow";
|
||||
@ -48,7 +59,8 @@ const groupToDosByDate = (toDos: IToDo[]) => {
|
||||
dateKey = "Next 30 Days";
|
||||
subDateKey = format(toDo.date, "MMM d");
|
||||
} else {
|
||||
return groups;
|
||||
dateKey = "Later";
|
||||
subDateKey = format(toDo.date, "MMM d, yyyy");
|
||||
}
|
||||
|
||||
if (!groups[dateKey]) {
|
||||
@ -58,7 +70,7 @@ const groupToDosByDate = (toDos: IToDo[]) => {
|
||||
};
|
||||
}
|
||||
|
||||
if (dateKey === "Next 30 Days" && subDateKey) {
|
||||
if ((dateKey === "Next 30 Days" || dateKey === "Later") && subDateKey) {
|
||||
if (!groups[dateKey].subgroups[subDateKey]) {
|
||||
groups[dateKey].subgroups[subDateKey] = [];
|
||||
}
|
||||
@ -138,14 +150,17 @@ const ToDosList = ({ isSettings }: { isSettings?: boolean }) => {
|
||||
};
|
||||
|
||||
const noDateToDos = groupedToDos["No Date"]?.items || [];
|
||||
const datedToDos = Object.keys(groupedToDos).filter(
|
||||
(key) => key !== "No Date"
|
||||
);
|
||||
const datedToDos = Object.keys(groupedToDos)
|
||||
.filter((key) => key !== "No Date")
|
||||
.sort((a, b) => {
|
||||
const order = ["Overdue", "Today", "Tomorrow", "Next 7 Days", "Next 30 Days", "Later"];
|
||||
return order.indexOf(a) - order.indexOf(b);
|
||||
});
|
||||
|
||||
const renderTodoGroup = (dateKey: string) => {
|
||||
const isExpanded = expandedGroups[dateKey] || false;
|
||||
|
||||
if (dateKey === "Next 30 Days") {
|
||||
if (dateKey === "Next 30 Days" || dateKey === "Later") {
|
||||
const subgroups = Object.entries(groupedToDos[dateKey].subgroups).sort(
|
||||
([dateA], [dateB]) => {
|
||||
const dateAObj = new Date(dateA);
|
||||
|
Reference in New Issue
Block a user