mirror of
https://github.com/urosran/cally.git
synced 2025-07-09 22:57:16 +00:00
85 lines
3.5 KiB
TypeScript
85 lines
3.5 KiB
TypeScript
import { useState, useEffect, useCallback } from "react";
|
|
import { useAuthContext } from "@/contexts/AuthContext";
|
|
import { useAtomValue } from "jotai";
|
|
import { useFetchAndSaveGoogleEvents } from "./useFetchAndSaveGoogleEvents";
|
|
import { useFetchAndSaveAppleEvents } from "./useFetchAndSaveAppleEvents";
|
|
import { useFetchAndSaveOutlookEvents } from "./useFetchAndSaveOutlookEvents";
|
|
import { selectedDateAtom } from "@/components/pages/calendar/atoms";
|
|
import { addDays, subDays, isBefore, isAfter, format } from "date-fns";
|
|
|
|
export const useSyncEvents = () => {
|
|
const { profileData } = useAuthContext();
|
|
const selectedDate = useAtomValue(selectedDateAtom);
|
|
|
|
const [lastSyncDate, setLastSyncDate] = useState<Date>(selectedDate);
|
|
const [lowerBoundDate, setLowerBoundDate] = useState<Date>(subDays(selectedDate, 6 * 30));
|
|
const [upperBoundDate, setUpperBoundDate] = useState<Date>(addDays(selectedDate, 6 * 30));
|
|
const [isSyncing, setIsSyncing] = useState(false);
|
|
const [error, setError] = useState(null);
|
|
|
|
const syncedRanges = useState<Set<string>>(new Set())[0];
|
|
|
|
const { mutateAsync: fetchAndSaveGoogleEvents } = useFetchAndSaveGoogleEvents();
|
|
const { mutateAsync: fetchAndSaveOutlookEvents } = useFetchAndSaveOutlookEvents();
|
|
const { mutateAsync: fetchAndSaveAppleEvents } = useFetchAndSaveAppleEvents();
|
|
|
|
const generateRangeKey = (startDate: Date, endDate: Date) => {
|
|
return `${format(startDate, "yyyy-MM-dd")}_${format(endDate, "yyyy-MM-dd")}`;
|
|
};
|
|
|
|
const syncEvents = useCallback(async () => {
|
|
setIsSyncing(true);
|
|
setError(null);
|
|
|
|
const newLowerBound = subDays(selectedDate, 6 * 30);
|
|
const newUpperBound = addDays(selectedDate, 6 * 30);
|
|
const rangeKey = generateRangeKey(newLowerBound, newUpperBound);
|
|
|
|
if (syncedRanges.has(rangeKey)) {
|
|
setIsSyncing(false);
|
|
return;
|
|
}
|
|
|
|
if (isBefore(selectedDate, lowerBoundDate) || isAfter(selectedDate, upperBoundDate)) {
|
|
try {
|
|
const googleEvents = Object.entries(profileData?.googleAccounts || {}).map(([email, { accessToken }]) =>
|
|
fetchAndSaveGoogleEvents({ token: accessToken, email, date: selectedDate })
|
|
);
|
|
|
|
const outlookEvents = Object.entries(profileData?.microsoftAccounts || {}).map(([email, token]) =>
|
|
fetchAndSaveOutlookEvents({ token, email, date: selectedDate })
|
|
);
|
|
|
|
const appleEvents = Object.entries(profileData?.appleAccounts || {}).map(([email, token]) =>
|
|
fetchAndSaveAppleEvents({ token, email, date: selectedDate })
|
|
);
|
|
|
|
await Promise.all([...googleEvents, ...outlookEvents, ...appleEvents]);
|
|
|
|
setLastSyncDate(selectedDate);
|
|
setLowerBoundDate(newLowerBound);
|
|
setUpperBoundDate(newUpperBound);
|
|
syncedRanges.add(rangeKey);
|
|
} catch (err) {
|
|
console.error("Error syncing events:", err);
|
|
setError(err);
|
|
} finally {
|
|
setIsSyncing(false);
|
|
}
|
|
} else {
|
|
setIsSyncing(false);
|
|
}
|
|
}, [selectedDate, lowerBoundDate, upperBoundDate, profileData, fetchAndSaveGoogleEvents, fetchAndSaveOutlookEvents, fetchAndSaveAppleEvents, syncedRanges]);
|
|
|
|
useEffect(() => {
|
|
syncEvents();
|
|
}, [selectedDate, syncEvents]);
|
|
|
|
return {
|
|
isSyncing,
|
|
error,
|
|
lastSyncDate,
|
|
lowerBoundDate,
|
|
upperBoundDate,
|
|
};
|
|
}; |