mirror of
https://github.com/urosran/cally.git
synced 2025-11-26 08:24:55 +00:00
Merge branch 'dev' of https://github.com/urosran/cally into dev
This commit is contained in:
@ -120,6 +120,10 @@ const AddChoreDialog = (addChoreDialogProps: IAddChoreDialog) => {
|
|||||||
Alert.alert('Alert', 'Cannot have a todo without any assignees');
|
Alert.alert('Alert', 'Cannot have a todo without any assignees');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (todo?.repeatType === REPEAT_TYPE.EVERY_WEEK && todo?.repeatDays?.length === 0) {
|
||||||
|
Alert.alert('Alert', 'Please select a specific day for the Weekly recurrence');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,9 +7,9 @@ import {AntDesign} from "@expo/vector-icons";
|
|||||||
import {IToDo} from "@/hooks/firebase/types/todoData";
|
import {IToDo} from "@/hooks/firebase/types/todoData";
|
||||||
import DropdownIcon from "@/assets/svgs/DropdownIcon";
|
import DropdownIcon from "@/assets/svgs/DropdownIcon";
|
||||||
import {Dropdown} from "react-native-element-dropdown";
|
import {Dropdown} from "react-native-element-dropdown";
|
||||||
import {useGetFamilyMembers} from "@/hooks/firebase/useGetFamilyMembers";
|
|
||||||
import {ProfileType, useAuthContext} from "@/contexts/AuthContext";
|
import {ProfileType, useAuthContext} from "@/contexts/AuthContext";
|
||||||
import {StyleSheet} from "react-native";
|
import {StyleSheet} from "react-native";
|
||||||
|
import {UserProfile} from "@/hooks/firebase/types/profileTypes";
|
||||||
|
|
||||||
const FILTER_OPTIONS = {
|
const FILTER_OPTIONS = {
|
||||||
ME: "Me",
|
ME: "Me",
|
||||||
@ -108,13 +108,11 @@ const resolveFilterOptions = (members, user) => {
|
|||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ToDosList = ({ isSettings }: { isSettings?: boolean }) => {
|
const ToDosList = ({ isSettings, members }: { isSettings?: boolean, members?: Array<UserProfile> }) => {
|
||||||
const { toDos } = useToDosContext();
|
const { toDos } = useToDosContext();
|
||||||
|
|
||||||
const [groupedToDos, setGroupedToDos] = useState([]);
|
const [groupedToDos, setGroupedToDos] = useState([]);
|
||||||
const { user } = useAuthContext()
|
const { user } = useAuthContext()
|
||||||
const { data: members } = useGetFamilyMembers();
|
|
||||||
|
|
||||||
|
|
||||||
const [expandedGroups, setExpandedGroups] = useState<{
|
const [expandedGroups, setExpandedGroups] = useState<{
|
||||||
[key: string]: boolean;
|
[key: string]: boolean;
|
||||||
@ -130,7 +128,7 @@ const ToDosList = ({ isSettings }: { isSettings?: boolean }) => {
|
|||||||
|
|
||||||
let selectedOption = options?.find((option) => option.value === user?.uid);
|
let selectedOption = options?.find((option) => option.value === user?.uid);
|
||||||
setSelectedFilter(selectedOption);
|
setSelectedFilter(selectedOption);
|
||||||
}, []);
|
}, [members]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (toDos && selectedFilter) {
|
if (toDos && selectedFilter) {
|
||||||
|
|||||||
@ -11,11 +11,14 @@ import FamilyChoresProgress from "./family-chores/FamilyChoresProgress";
|
|||||||
import UserChoresProgress from "./user-chores/UserChoresProgress";
|
import UserChoresProgress from "./user-chores/UserChoresProgress";
|
||||||
import { useAtom } from "jotai";
|
import { useAtom } from "jotai";
|
||||||
import { toDosPageIndex } from "../calendar/atoms";
|
import { toDosPageIndex } from "../calendar/atoms";
|
||||||
|
import {useGetFamilyMembers} from "@/hooks/firebase/useGetFamilyMembers";
|
||||||
|
|
||||||
const ToDosPage = () => {
|
const ToDosPage = () => {
|
||||||
const { profileData } = useAuthContext();
|
const { profileData } = useAuthContext();
|
||||||
const [pageIndex, setPageIndex] = useAtom(toDosPageIndex);
|
const [pageIndex, setPageIndex] = useAtom(toDosPageIndex);
|
||||||
|
|
||||||
|
const { data: members } = useGetFamilyMembers();
|
||||||
|
|
||||||
const { width, height } = Dimensions.get("screen");
|
const { width, height } = Dimensions.get("screen");
|
||||||
const pageLink = (
|
const pageLink = (
|
||||||
<TouchableOpacity onPress={() => setPageIndex(1)}>
|
<TouchableOpacity onPress={() => setPageIndex(1)}>
|
||||||
@ -65,7 +68,7 @@ const ToDosPage = () => {
|
|||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
<ToDosList />
|
<ToDosList members={members} />
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import {useMutation, useQueryClient} from "react-query";
|
import { useMutation, useQueryClient } from "react-query";
|
||||||
import firestore from "@react-native-firebase/firestore";
|
import firestore from "@react-native-firebase/firestore";
|
||||||
import {useAuthContext} from "@/contexts/AuthContext";
|
import { useAuthContext } from "@/contexts/AuthContext";
|
||||||
import {DAYS_OF_WEEK_ENUM, IToDo, REPEAT_TYPE} from "@/hooks/firebase/types/todoData";
|
import { DAYS_OF_WEEK_ENUM, IToDo, REPEAT_TYPE } from "@/hooks/firebase/types/todoData";
|
||||||
import {addDays, addMonths, addWeeks, addYears, compareAsc, format, subDays} from "date-fns";
|
import { addMonths, addWeeks, addYears } from "date-fns";
|
||||||
|
|
||||||
export const daysOfWeek = [
|
export const daysOfWeek = [
|
||||||
DAYS_OF_WEEK_ENUM.MONDAY,
|
DAYS_OF_WEEK_ENUM.MONDAY,
|
||||||
@ -13,6 +13,66 @@ export const daysOfWeek = [
|
|||||||
DAYS_OF_WEEK_ENUM.SATURDAY,
|
DAYS_OF_WEEK_ENUM.SATURDAY,
|
||||||
DAYS_OF_WEEK_ENUM.SUNDAY];
|
DAYS_OF_WEEK_ENUM.SUNDAY];
|
||||||
|
|
||||||
|
const getNextDailyDates = (date) => {
|
||||||
|
const today = new Date();
|
||||||
|
const dates = [];
|
||||||
|
|
||||||
|
for (let weekOffset = 0; weekOffset < 2; weekOffset++) {
|
||||||
|
const targetDate = addWeeks(date, weekOffset);
|
||||||
|
if (targetDate > today) {
|
||||||
|
dates.push(targetDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dates;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getNextWeeklyDates = (selectedDays, date) => {
|
||||||
|
const today = new Date();
|
||||||
|
const currentDay = date.getDay();
|
||||||
|
const dates = [];
|
||||||
|
|
||||||
|
for (let week = 0; week < 2; week++) {
|
||||||
|
selectedDays.forEach((day) => {
|
||||||
|
const targetDay = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'].indexOf(day);
|
||||||
|
const diff = (targetDay - currentDay + 7) % 7 + week * 7; // Move to the next week
|
||||||
|
const nextDate = new Date(today);
|
||||||
|
nextDate.setDate(date.getDate() + diff);
|
||||||
|
dates.push(nextDate);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return dates;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getNextMonthlyDates = (date) => {
|
||||||
|
const today = new Date();
|
||||||
|
const dates = [];
|
||||||
|
|
||||||
|
for (let monthOffset = 0; monthOffset < 12; monthOffset++) {
|
||||||
|
const targetDate = addMonths(date, monthOffset);
|
||||||
|
if (targetDate > today) {
|
||||||
|
dates.push(targetDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dates;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getNextYearlyDates = (date) => {
|
||||||
|
const today = new Date();
|
||||||
|
const dates = [];
|
||||||
|
|
||||||
|
for (let yearOffset = 0; yearOffset < 5; yearOffset++) {
|
||||||
|
const nextYear = addYears(date, yearOffset);
|
||||||
|
if (nextYear > today) {
|
||||||
|
dates.push(nextYear);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dates;
|
||||||
|
};
|
||||||
|
|
||||||
export const useCreateTodo = () => {
|
export const useCreateTodo = () => {
|
||||||
const { user: currentUser, profileData } = useAuthContext();
|
const { user: currentUser, profileData } = useAuthContext();
|
||||||
const queryClients = useQueryClient();
|
const queryClients = useQueryClient();
|
||||||
@ -28,93 +88,50 @@ export const useCreateTodo = () => {
|
|||||||
.collection("Todos")
|
.collection("Todos")
|
||||||
.add(originalTodo);
|
.add(originalTodo);
|
||||||
} else {
|
} else {
|
||||||
// Create the one original to do
|
|
||||||
const newDoc = firestore().collection('Todos').doc();
|
|
||||||
let originalTodo = {...todoData, id: newDoc.id, familyId: profileData?.familyId, creatorId: currentUser?.uid, connectedTodoId: newDoc.id};
|
|
||||||
|
|
||||||
originalTodo = resolveTodoAlternatingAssignees(todoData, originalTodo, 0);
|
let nextDates;
|
||||||
|
if (todoData.repeatType === REPEAT_TYPE.DAILY) {
|
||||||
|
nextDates = getNextDailyDates(todoData.date);
|
||||||
|
} else if (todoData.repeatType === REPEAT_TYPE.EVERY_WEEK) {
|
||||||
|
nextDates = getNextWeeklyDates(todoData.repeatDays, todoData.date);
|
||||||
|
} else if (todoData.repeatType === REPEAT_TYPE.ONCE_A_MONTH) {
|
||||||
|
nextDates = getNextMonthlyDates(todoData.date);
|
||||||
|
} else if (todoData.repeatType === REPEAT_TYPE.ONCE_A_YEAR) {
|
||||||
|
nextDates = getNextYearlyDates(todoData.date);
|
||||||
|
}
|
||||||
|
|
||||||
await firestore()
|
const todosRef = firestore().collection("Todos");
|
||||||
.collection("Todos")
|
const ruleDocRef = todosRef.doc();
|
||||||
.add(originalTodo);
|
const ruleDoc = await todosRef.add(
|
||||||
|
{...todoData,
|
||||||
|
id: ruleDocRef.id,
|
||||||
|
familyId: profileData?.familyId,
|
||||||
|
creatorId: currentUser?.uid,
|
||||||
|
connectedTodoId: ruleDocRef.id,}
|
||||||
|
);
|
||||||
|
|
||||||
const batch = firestore().batch();
|
const batch = firestore().batch();
|
||||||
|
nextDates.forEach((date, index) => {
|
||||||
|
const newDocRef = todosRef.doc();
|
||||||
|
|
||||||
if (todoData.repeatType === REPEAT_TYPE.DAILY) {
|
let assignee;
|
||||||
// for the next 52 weeks
|
if (todoData.assignees && todoData.rotate && todoData?.assignees?.length !== 0) {
|
||||||
for (let i = 1; i < 52; i++) {
|
assignee = todoData.assignees[index % todoData.assignees.length];
|
||||||
let date = originalTodo.date;
|
|
||||||
const nextWeek = addWeeks(date, i);
|
|
||||||
|
|
||||||
let docRef = firestore().collection("Todos").doc();
|
|
||||||
let newTodo = { ...originalTodo, id: docRef.id, date: nextWeek, connectedTodoId: newDoc.id };
|
|
||||||
newTodo = resolveTodoAlternatingAssignees(todoData, newTodo, i);
|
|
||||||
|
|
||||||
batch.set(docRef, newTodo);
|
|
||||||
}
|
|
||||||
} else if (todoData.repeatType === REPEAT_TYPE.EVERY_WEEK) {
|
|
||||||
|
|
||||||
let date = originalTodo.date;
|
|
||||||
let repeatDays = originalTodo.repeatDays;
|
|
||||||
const dates = [];
|
|
||||||
|
|
||||||
const originalDateDay = format(date, 'EEEE');
|
|
||||||
const originalNumber = daysOfWeek.indexOf(originalDateDay);
|
|
||||||
repeatDays?.forEach((day) => {
|
|
||||||
let number = daysOfWeek.indexOf(day);
|
|
||||||
let newDate;
|
|
||||||
if (originalNumber > number) {
|
|
||||||
let diff = originalNumber - number;
|
|
||||||
newDate = subDays(date, diff);
|
|
||||||
} else {
|
|
||||||
let diff = number - originalNumber;
|
|
||||||
newDate = addDays(date, diff);
|
|
||||||
}
|
}
|
||||||
dates.push(newDate);
|
|
||||||
});
|
|
||||||
|
|
||||||
let index = 1;
|
const nextTodo = {
|
||||||
for (let i = 0; i < 52; i++) {
|
...todoData,
|
||||||
dates?.forEach((dateToAdd) => {
|
date: date,
|
||||||
index ++;
|
id: newDocRef.id,
|
||||||
let newTodoDate = addWeeks(dateToAdd, i);
|
familyId: profileData?.familyId,
|
||||||
if (compareAsc(newTodoDate, originalTodo.date) !== 0) {
|
creatorId: currentUser?.uid,
|
||||||
|
connectedTodoId: ruleDocRef.id,
|
||||||
|
assignees: assignee ? [assignee] : null
|
||||||
|
}
|
||||||
|
|
||||||
let docRef = firestore().collection("Todos").doc();
|
batch.set(newDocRef, nextTodo)
|
||||||
let newTodo = { ...originalTodo, id: docRef.id, date: newTodoDate, connectedTodoId: newDoc.id };
|
|
||||||
newTodo = resolveTodoAlternatingAssignees(todoData, newTodo, index);
|
|
||||||
|
|
||||||
batch.set(docRef, newTodo);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
} else if (todoData.repeatType === REPEAT_TYPE.ONCE_A_MONTH) {
|
);
|
||||||
|
|
||||||
// for the next 12 months
|
|
||||||
for (let i = 1; i < 12; i++) {
|
|
||||||
let date = originalTodo.date;
|
|
||||||
const nextMonth = addMonths(date, i);
|
|
||||||
|
|
||||||
let docRef = firestore().collection("Todos").doc();
|
|
||||||
let newTodo = { ...originalTodo, id: docRef.id, date: nextMonth, connectedTodoId: newDoc.id };
|
|
||||||
newTodo = resolveTodoAlternatingAssignees(todoData, newTodo, i);
|
|
||||||
|
|
||||||
batch.set(docRef, newTodo);
|
|
||||||
}
|
|
||||||
} else if (todoData.repeatType === REPEAT_TYPE.ONCE_A_YEAR) {
|
|
||||||
|
|
||||||
// for the next 5 years
|
|
||||||
for (let i = 1; i < 5; i++) {
|
|
||||||
let date = originalTodo.date;
|
|
||||||
const nextMonth = addYears(date, i);
|
|
||||||
|
|
||||||
let docRef = firestore().collection("Todos").doc();
|
|
||||||
let newTodo = { ...originalTodo, id: docRef.id, date: nextMonth, connectedTodoId: newDoc.id };
|
|
||||||
newTodo = resolveTodoAlternatingAssignees(todoData, newTodo, i);
|
|
||||||
|
|
||||||
batch.set(docRef, newTodo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await batch.commit();
|
await batch.commit();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user