mirror of
https://github.com/urosran/cally.git
synced 2025-07-10 07:07:16 +00:00
140 lines
6.2 KiB
TypeScript
140 lines
6.2 KiB
TypeScript
import {useMutation, useQueryClient} from "react-query";
|
|
import firestore from "@react-native-firebase/firestore";
|
|
import {useAuthContext} from "@/contexts/AuthContext";
|
|
import {DAYS_OF_WEEK_ENUM, IToDo, REPEAT_TYPE} from "@/hooks/firebase/types/todoData";
|
|
import {addDays, addMonths, addWeeks, addYears, compareAsc, format, subDays} from "date-fns";
|
|
|
|
export const daysOfWeek = [
|
|
DAYS_OF_WEEK_ENUM.MONDAY,
|
|
DAYS_OF_WEEK_ENUM.TUESDAY,
|
|
DAYS_OF_WEEK_ENUM.WEDNESDAY,
|
|
DAYS_OF_WEEK_ENUM.THURSDAY,
|
|
DAYS_OF_WEEK_ENUM.FRIDAY,
|
|
DAYS_OF_WEEK_ENUM.SATURDAY,
|
|
DAYS_OF_WEEK_ENUM.SUNDAY];
|
|
|
|
export const useCreateTodo = () => {
|
|
const { user: currentUser, profileData } = useAuthContext();
|
|
const queryClients = useQueryClient();
|
|
|
|
return useMutation({
|
|
mutationKey: ["createTodo"],
|
|
mutationFn: async (todoData: Partial<IToDo>) => {
|
|
try {
|
|
if (todoData.repeatType === REPEAT_TYPE.NONE) {
|
|
const newDoc = firestore().collection('Todos').doc();
|
|
let originalTodo = {...todoData, id: newDoc.id, familyId: profileData?.familyId, creatorId: currentUser?.uid}
|
|
await firestore()
|
|
.collection("Todos")
|
|
.add(originalTodo);
|
|
} 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);
|
|
|
|
await firestore()
|
|
.collection("Todos")
|
|
.add(originalTodo);
|
|
|
|
const batch = firestore().batch();
|
|
|
|
if (todoData.repeatType === REPEAT_TYPE.DAILY) {
|
|
// for the next 52 weeks
|
|
for (let i = 1; i < 52; i++) {
|
|
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;
|
|
for (let i = 0; i < 52; i++) {
|
|
dates?.forEach((dateToAdd) => {
|
|
index ++;
|
|
let newTodoDate = addWeeks(dateToAdd, i);
|
|
if (compareAsc(newTodoDate, originalTodo.date) !== 0) {
|
|
|
|
let docRef = firestore().collection("Todos").doc();
|
|
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();
|
|
}
|
|
} catch (e) {
|
|
console.error(e)
|
|
}
|
|
},
|
|
onSuccess: () => {
|
|
queryClients.invalidateQueries("todos")
|
|
}
|
|
})
|
|
}
|
|
|
|
export const resolveTodoAlternatingAssignees = (todoData, newTodo, i) => {
|
|
if (todoData.assignees && todoData.rotate && todoData?.assignees?.length !== 0) {
|
|
const assignees = todoData.assignees;
|
|
const assignee = assignees[i % assignees.length];
|
|
|
|
newTodo = {...newTodo, assignees: [assignee]};
|
|
}
|
|
|
|
return newTodo;
|
|
} |