Files
cally/hooks/firebase/useCreateTodo.ts
2024-12-15 15:31:55 +01:00

157 lines
5.5 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 { addMonths, addWeeks, addYears } 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];
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 = () => {
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 {
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);
}
const todosRef = firestore().collection("Todos");
const ruleDocRef = todosRef.doc();
const ruleDoc = await todosRef.add(
{...todoData,
id: ruleDocRef.id,
familyId: profileData?.familyId,
creatorId: currentUser?.uid,
connectedTodoId: ruleDocRef.id,}
);
const batch = firestore().batch();
nextDates.forEach((date, index) => {
const newDocRef = todosRef.doc();
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: ruleDocRef.id,
assignees: assignee ? [assignee] : null
}
batch.set(newDocRef, nextTodo)
}
);
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;
}