mirror of
https://github.com/urosran/cally.git
synced 2025-07-16 18:16:17 +00:00
- Improved the todo update
This commit is contained in:
@ -14,14 +14,19 @@ export const daysOfWeek = [
|
||||
DAYS_OF_WEEK_ENUM.SATURDAY,
|
||||
DAYS_OF_WEEK_ENUM.SUNDAY];
|
||||
|
||||
export const getNextDailyDates = (date) => {
|
||||
export const getNextDailyDates = (date, includeToday) => {
|
||||
const today = new Date();
|
||||
const dates = [];
|
||||
|
||||
for (let weekOffset = 0; weekOffset < 52; weekOffset++) {
|
||||
const targetDate = addWeeks(date, weekOffset);
|
||||
if (targetDate > today) {
|
||||
|
||||
if (includeToday) {
|
||||
dates.push(targetDate);
|
||||
} else {
|
||||
if (targetDate > today) {
|
||||
dates.push(targetDate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,28 +51,36 @@ export const getNextWeeklyDates = (selectedDays, date) => {
|
||||
return dates;
|
||||
};
|
||||
|
||||
export const getNextMonthlyDates = (date) => {
|
||||
export const getNextMonthlyDates = (date, includeToday) => {
|
||||
const today = new Date();
|
||||
const dates = [];
|
||||
|
||||
for (let monthOffset = 0; monthOffset < 12; monthOffset++) {
|
||||
const targetDate = addMonths(date, monthOffset);
|
||||
if (targetDate > today) {
|
||||
if (includeToday) {
|
||||
dates.push(targetDate);
|
||||
} else {
|
||||
if (targetDate > today) {
|
||||
dates.push(targetDate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dates;
|
||||
};
|
||||
|
||||
export const getNextYearlyDates = (date) => {
|
||||
export const getNextYearlyDates = (date, includeToday) => {
|
||||
const today = new Date();
|
||||
const dates = [];
|
||||
|
||||
for (let yearOffset = 0; yearOffset < 5; yearOffset++) {
|
||||
const nextYear = addYears(date, yearOffset);
|
||||
if (nextYear > today) {
|
||||
if (includeToday) {
|
||||
dates.push(nextYear);
|
||||
} else {
|
||||
if (nextYear > today) {
|
||||
dates.push(nextYear);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,13 +105,13 @@ export const useCreateTodo = () => {
|
||||
|
||||
let nextDates;
|
||||
if (todoData.repeatType === REPEAT_TYPE.DAILY) {
|
||||
nextDates = getNextDailyDates(todoData.date);
|
||||
nextDates = getNextDailyDates(todoData.date, false);
|
||||
} 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);
|
||||
nextDates = getNextMonthlyDates(todoData.date, false);
|
||||
} else if (todoData.repeatType === REPEAT_TYPE.ONCE_A_YEAR) {
|
||||
nextDates = getNextYearlyDates(todoData.date);
|
||||
nextDates = getNextYearlyDates(todoData.date, false);
|
||||
}
|
||||
|
||||
const todosRef = firestore().collection("Todos");
|
||||
|
@ -1,9 +1,14 @@
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import firestore from "@react-native-firebase/firestore";
|
||||
import {IToDo, REPEAT_TYPE} from "@/hooks/firebase/types/todoData";
|
||||
import {addDays, addMonths, addWeeks, addYears, compareAsc, format, subDays} from "date-fns";
|
||||
import {daysOfWeek, resolveTodoAlternatingAssignees} from "@/hooks/firebase/useCreateTodo";
|
||||
import {useAuthContext} from "@/contexts/AuthContext";
|
||||
import { IToDo, REPEAT_TYPE } from "@/hooks/firebase/types/todoData";
|
||||
import { compareAsc, format } from "date-fns";
|
||||
import {
|
||||
getNextDailyDates,
|
||||
getNextMonthlyDates,
|
||||
getNextWeeklyDates,
|
||||
getNextYearlyDates
|
||||
} from "@/hooks/firebase/useCreateTodo";
|
||||
import { useAuthContext } from "@/contexts/AuthContext";
|
||||
|
||||
export const useUpdateTodo = () => {
|
||||
const { user: currentUser, profileData } = useAuthContext();
|
||||
@ -14,9 +19,22 @@ export const useUpdateTodo = () => {
|
||||
mutationFn: async (todoData: Partial<IToDo>) => {
|
||||
try {
|
||||
if (todoData.connectedTodoId) {
|
||||
console.log("CONNECTED")
|
||||
const snapshot = await firestore()
|
||||
.collection("Todos")
|
||||
|
||||
let nextDates;
|
||||
if (todoData.repeatType === REPEAT_TYPE.DAILY) {
|
||||
nextDates = getNextDailyDates(todoData.date, true);
|
||||
} 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, true);
|
||||
} else if (todoData.repeatType === REPEAT_TYPE.ONCE_A_YEAR) {
|
||||
nextDates = getNextYearlyDates(todoData.date, true);
|
||||
}
|
||||
|
||||
const todosRef = firestore().collection("Todos");
|
||||
const batch = firestore().batch();
|
||||
|
||||
const snapshot = await todosRef
|
||||
.where("connectedTodoId", "==", todoData.connectedTodoId)
|
||||
.get();
|
||||
const connectedTodos = snapshot.docs.map((doc) => {
|
||||
@ -30,131 +48,66 @@ export const useUpdateTodo = () => {
|
||||
};
|
||||
}) as IToDo[];
|
||||
|
||||
console.log("CONNECTED TODO");
|
||||
let filteredTodos = connectedTodos?.filter((item) => compareAsc(format(item.date, 'yyyy-MM-dd'), format(todoData.date, 'yyyy-MM-dd')) === 1 ||
|
||||
compareAsc(format(item.date, 'yyyy-MM-dd'), format(todoData.date, 'yyyy-MM-dd')) === 0).sort((a,b) =>{
|
||||
return b.date?.getSeconds() - a.date?.getSeconds();
|
||||
});
|
||||
|
||||
let firstTodo = filteredTodos?.[0];
|
||||
const batch = firestore().batch();
|
||||
if (compareAsc(format(firstTodo?.date, 'yyyy-MM-dd'), format(todoData.date, 'yyyy-MM-dd')) !== 0 || firstTodo?.repeatType !== todoData.repeatType) {
|
||||
|
||||
console.log("DELETE");
|
||||
filteredTodos?.forEach((item) => {
|
||||
batch.delete(item.ref);
|
||||
});
|
||||
|
||||
if (todoData.repeatType === REPEAT_TYPE.NONE) {
|
||||
|
||||
console.log("NONE");
|
||||
const newDoc = firestore().collection('Todos').doc();
|
||||
let originalTodo = {...todoData, id: newDoc.id, familyId: profileData?.familyId, creatorId: currentUser?.uid}
|
||||
batch.set(newDoc, originalTodo);
|
||||
} else if (todoData.repeatType === REPEAT_TYPE.DAILY) {
|
||||
console.log("DAILY");
|
||||
// for the next 52 weeks
|
||||
for (let i = 0; i < 52; i++) {
|
||||
let date = todoData?.date;
|
||||
const nextWeek = addWeeks(date, i);
|
||||
|
||||
let docRef = firestore().collection("Todos").doc();
|
||||
let newTodo = { ...todoData, id: docRef.id, date: nextWeek, connectedTodoId: firstTodo?.connectedTodoId };
|
||||
newTodo = resolveTodoAlternatingAssignees(todoData, newTodo, i);
|
||||
batch.set(docRef, newTodo);
|
||||
}
|
||||
} else if (todoData.repeatType === REPEAT_TYPE.EVERY_WEEK) {
|
||||
|
||||
console.log("EVERY WEEK");
|
||||
let date = todoData?.date;
|
||||
let repeatDays = todoData?.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 todosToAddCycles = 52;
|
||||
if (firstTodo?.repeatType === REPEAT_TYPE.EVERY_WEEK) {
|
||||
todosToAddCycles = filteredTodos?.length / firstTodo?.repeatDays?.length;
|
||||
}
|
||||
console.log(todosToAddCycles);
|
||||
let newDoc = firestore().collection("Todos").doc();
|
||||
let originalTodo = { ...todoData, id: newDoc.id, date: todoData.date, connectedTodoId: newDoc?.id };
|
||||
originalTodo = resolveTodoAlternatingAssignees(todoData, originalTodo, 0);
|
||||
batch.set(newDoc, originalTodo);
|
||||
|
||||
console.log(dates);
|
||||
let index = 1;
|
||||
for (let i = 0; i <= todosToAddCycles; i++) {
|
||||
dates?.forEach((dateToAdd) => {
|
||||
index++;
|
||||
let newTodoDate = addWeeks(dateToAdd, i);
|
||||
if (compareAsc(newTodoDate, originalTodo.date) !== 0) {
|
||||
|
||||
let docRef = firestore().collection("Todos").doc();
|
||||
let newTodo = { ...todoData, 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) {
|
||||
|
||||
console.log("ONCE A MONTH");
|
||||
// for the next 12 months
|
||||
for (let i = 0; i < 12; i++) {
|
||||
let date = todoData?.date;
|
||||
const nextMonth = addMonths(date, i);
|
||||
|
||||
let docRef = firestore().collection("Todos").doc();
|
||||
let newTodo = { ...todoData, id: docRef.id, date: nextMonth, connectedTodoId: firstTodo?.connectedTodoId };
|
||||
newTodo = resolveTodoAlternatingAssignees(todoData, newTodo, i);
|
||||
batch.set(docRef, newTodo);
|
||||
}
|
||||
} else if (todoData.repeatType === REPEAT_TYPE.ONCE_A_YEAR) {
|
||||
|
||||
console.log("ONCE A YEAR");
|
||||
// for the next 5 years
|
||||
for (let i = 0; i < 5; i++) {
|
||||
let date = todoData?.date;
|
||||
const nextMonth = addYears(date, i);
|
||||
|
||||
let docRef = firestore().collection("Todos").doc();
|
||||
let newTodo = { ...todoData, id: docRef.id, date: nextMonth, connectedTodoId: firstTodo?.connectedTodoId };
|
||||
newTodo = resolveTodoAlternatingAssignees(todoData, newTodo, i);
|
||||
batch.set(docRef, newTodo);
|
||||
}
|
||||
// Update existing todos or create new ones
|
||||
filteredTodos?.map((todo, index) => {
|
||||
const newDate = nextDates[index];
|
||||
let assignee;
|
||||
if (todoData.assignees && todoData.rotate && todoData?.assignees?.length !== 0) {
|
||||
assignee = todoData.assignees[index % todoData.assignees.length];
|
||||
}
|
||||
|
||||
await batch.commit();
|
||||
} else if (firstTodo?.repeatDays !== todoData.repeatDays) {
|
||||
if (newDate) {
|
||||
const nextTodo = {
|
||||
...todoData,
|
||||
date: newDate,
|
||||
assignees: assignee ? [assignee] : todoData.assignees
|
||||
}
|
||||
let docRef = todo.ref;
|
||||
batch.update(docRef, nextTodo)
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
console.log("UPDATE REPEAT DAYS");
|
||||
await updateRepeatDaysTodos(batch, todoData, firstTodo, filteredTodos)
|
||||
} else {
|
||||
filteredTodos?.forEach((item) => {
|
||||
const existingDates = filteredTodos?.map((todo) => todo.date);
|
||||
nextDates
|
||||
.filter((date) => !existingDates.includes(date))
|
||||
.map((date, index) => {
|
||||
const newDocRef = todosRef.doc();
|
||||
|
||||
console.log("UPDATE");
|
||||
batch.update(item.ref, {...todoData, date: item.date});
|
||||
})
|
||||
await batch.commit();
|
||||
}
|
||||
let assignee;
|
||||
if (todoData.assignees && todoData.rotate && todoData?.assignees?.length !== 0) {
|
||||
assignee = todoData.assignees[index % todoData.assignees.length];
|
||||
}
|
||||
|
||||
const nextTodo = {
|
||||
...todoData,
|
||||
date: date,
|
||||
id: newDocRef.id,
|
||||
familyId: profileData?.familyId,
|
||||
creatorId: currentUser?.uid,
|
||||
connectedTodoId: todoData.connectedTodoId,
|
||||
assignees: assignee ? [assignee] : todoData.assignees
|
||||
}
|
||||
|
||||
batch.set(newDocRef, nextTodo)
|
||||
});
|
||||
|
||||
// Remove unmatched todos
|
||||
const unmatchedTodos = filteredTodos?.filter(
|
||||
(item) => !nextDates.includes(item.date)
|
||||
);
|
||||
unmatchedTodos.map((item) =>
|
||||
batch.delete(item.ref)
|
||||
);
|
||||
|
||||
await batch.commit();
|
||||
} else {
|
||||
console.log("REGULAR UPDATE");
|
||||
console.log(todoData);
|
||||
await firestore()
|
||||
.collection("Todos")
|
||||
.doc(todoData.id)
|
||||
@ -168,62 +121,4 @@ export const useUpdateTodo = () => {
|
||||
queryClients.invalidateQueries({queryKey: ["todos"]})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const updateRepeatDaysTodos = async (batch: any, todoData: IToDo, firstTodo: IToDo, filteredTodos: IToDo[]) => {
|
||||
const todosToAddCycles = filteredTodos?.length / firstTodo?.repeatDays?.length;
|
||||
console.log(todosToAddCycles);
|
||||
|
||||
filteredTodos?.forEach((item) => {
|
||||
|
||||
batch.update(item.ref, {...todoData, date: item.date});
|
||||
})
|
||||
|
||||
let newRepeatDays = todoData.repeatDays?.filter((element) => firstTodo?.repeatDays?.indexOf(element) === -1);
|
||||
let removeRepeatDays = firstTodo?.repeatDays?.filter((element) => todoData?.repeatDays?.indexOf(element) === -1);
|
||||
const dates = [];
|
||||
|
||||
let date = firstTodo?.date;
|
||||
const originalDateDay = format(date, 'EEEE');
|
||||
const originalNumber = daysOfWeek.indexOf(originalDateDay);
|
||||
newRepeatDays?.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 = 0;
|
||||
for (let i = 0; i < todosToAddCycles; i++) {
|
||||
dates?.forEach((dateToAdd) => {
|
||||
index ++;
|
||||
let newTodoDate = addWeeks(dateToAdd, i);
|
||||
if (compareAsc(newTodoDate, firstTodo?.date) !== 0) {
|
||||
let newTodo = {...todoData, date: newTodoDate};
|
||||
newTodo = resolveTodoAlternatingAssignees(todoData, newTodo, index);
|
||||
|
||||
let docRef = firestore().collection("Todos").doc();
|
||||
batch.set(docRef, newTodo);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
removeRepeatDays?.forEach((removeDay) => {
|
||||
filteredTodos?.forEach((item) => {
|
||||
|
||||
let todoDate = item.date;
|
||||
const todoDateDay = format(todoDate, 'EEEE');
|
||||
|
||||
if (todoDateDay === removeDay) {
|
||||
batch.delete(item.ref);
|
||||
}
|
||||
})
|
||||
})
|
||||
await batch.commit();
|
||||
}
|
||||
};
|
Reference in New Issue
Block a user