mirror of
https://github.com/urosran/cally.git
synced 2025-07-10 15:17:17 +00:00
206 lines
9.2 KiB
TypeScript
206 lines
9.2 KiB
TypeScript
import { useMutation, useQueryClient } from "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} from "@/hooks/firebase/useCreateTodo";
|
|
import {useAuthContext} from "@/contexts/AuthContext";
|
|
|
|
export const useUpdateTodo = () => {
|
|
const { user: currentUser, profileData } = useAuthContext();
|
|
const queryClients = useQueryClient()
|
|
|
|
return useMutation({
|
|
mutationKey: ["updateTodo"],
|
|
mutationFn: async (todoData: Partial<IToDo>) => {
|
|
try {
|
|
const snapshot = await firestore()
|
|
.collection("Todos")
|
|
.where("connectedTodoId", "==", todoData.connectedTodoId)
|
|
.get();
|
|
|
|
if (todoData.connectedTodoId) {
|
|
const connectedTodos = snapshot.docs.map((doc) => {
|
|
const data = doc.data();
|
|
|
|
return {
|
|
...data,
|
|
id: doc.id,
|
|
date: data.date ? new Date(data.date.seconds * 1000) : null,
|
|
ref: doc.ref
|
|
};
|
|
}) 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.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 = 4;
|
|
if (firstTodo?.repeatType === REPEAT_TYPE.EVERY_WEEK) {
|
|
todosToAddCycles = filteredTodos?.length / firstTodo?.repeatDays?.length;
|
|
}
|
|
console.log(todosToAddCycles);
|
|
let newDoc = firestore().collection("Todos").doc();
|
|
const newTodo = { ...todoData, id: newDoc.id, date: todoData.date, connectedTodoId: newDoc?.id };
|
|
batch.set(newDoc, newTodo);
|
|
|
|
console.log(dates);
|
|
for (let i = 0; i < todosToAddCycles; i++) {
|
|
dates?.forEach((dateToAdd) => {
|
|
let newTodoDate = addWeeks(dateToAdd, i);
|
|
|
|
console.log("ENTER")
|
|
let docRef = firestore().collection("Todos").doc();
|
|
const newTodo = { ...todoData, id: docRef.id, date: newTodoDate, connectedTodoId: newDoc?.id };
|
|
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);
|
|
const newTodo = { ...todoData, date: nextMonth, connectedTodoId: firstTodo?.connectedTodoId };
|
|
|
|
let docRef = firestore().collection("Todos").doc();
|
|
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);
|
|
const newTodo = { ...todoData, date: nextMonth, connectedTodoId: firstTodo?.connectedTodoId };
|
|
|
|
let docRef = firestore().collection("Todos").doc();
|
|
batch.set(docRef, newTodo);
|
|
}
|
|
}
|
|
|
|
await batch.commit();
|
|
} else if (firstTodo?.repeatDays !== todoData.repeatDays) {
|
|
|
|
console.log("UPDATE REPEAT DAYS");
|
|
await updateRepeatDaysTodos(batch, todoData, firstTodo, filteredTodos)
|
|
} else {
|
|
filteredTodos?.forEach((item) => {
|
|
|
|
console.log("UPDATE");
|
|
batch.update(item.ref, {...todoData, date: item.date});
|
|
})
|
|
await batch.commit();
|
|
}
|
|
} else {
|
|
console.log("REGULAR UPDATE");
|
|
console.log(todoData);
|
|
await firestore()
|
|
.collection("Todos")
|
|
.doc(todoData.id)
|
|
.update(todoData);
|
|
}
|
|
} catch (e) {
|
|
console.error(e)
|
|
}
|
|
},
|
|
onSuccess: () => {
|
|
queryClients.invalidateQueries("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);
|
|
});
|
|
|
|
for (let i = 0; i < todosToAddCycles; i++) {
|
|
dates?.forEach((dateToAdd) => {
|
|
let newTodoDate = addWeeks(dateToAdd, i);
|
|
if (compareAsc(newTodoDate, firstTodo?.date) !== 0) {
|
|
const newTodo = {...todoData, date: newTodoDate};
|
|
|
|
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();
|
|
} |