mirror of
https://github.com/urosran/cally.git
synced 2025-07-10 07:07:16 +00:00
107 lines
4.6 KiB
TypeScript
107 lines
4.6 KiB
TypeScript
import { useMutation, useQueryClient } from "react-query";
|
|
import { fetchGoogleCalendarEvents } from "@/calendar-integration/google-calendar-utils";
|
|
import { useAuthContext } from "@/contexts/AuthContext";
|
|
import { useCreateEventsFromProvider } from "@/hooks/firebase/useCreateEvent";
|
|
import { useClearTokens } from "@/hooks/firebase/useClearTokens";
|
|
import { useUpdateUserData } from "@/hooks/firebase/useUpdateUserData";
|
|
|
|
export const useFetchAndSaveGoogleEvents = () => {
|
|
const queryClient = useQueryClient();
|
|
const { profileData } = useAuthContext();
|
|
const { mutateAsync: createEventsFromProvider } = useCreateEventsFromProvider();
|
|
const { mutateAsync: clearToken } = useClearTokens();
|
|
const { mutateAsync: updateUserData } = useUpdateUserData();
|
|
|
|
return useMutation({
|
|
mutationKey: ["fetchAndSaveGoogleEvents", "sync"],
|
|
mutationFn: async ({ token, email, date, refreshToken }: { token?: string; refreshToken?: string; email?: string; date?: Date }) => {
|
|
const baseDate = date || new Date();
|
|
const timeMin = new Date(baseDate.setMonth(baseDate.getMonth() - 1)).toISOString().slice(0, -5) + "Z";
|
|
const timeMax = new Date(baseDate.setMonth(baseDate.getMonth() + 2)).toISOString().slice(0, -5) + "Z";
|
|
|
|
console.log("Token: ", token);
|
|
|
|
const tryFetchEvents = async (isRetry = false) => {
|
|
try {
|
|
const response = await fetchGoogleCalendarEvents(
|
|
token,
|
|
email,
|
|
profileData?.familyId,
|
|
timeMin,
|
|
timeMax
|
|
);
|
|
|
|
if (!response.success) {
|
|
await clearToken({ email: email!, provider: "google" });
|
|
return; // Stop refetching if clearing the token
|
|
}
|
|
|
|
console.log("Google Calendar events fetched:", response);
|
|
|
|
const items = response?.googleEvents?.map((item) => {
|
|
if (item.allDay) {
|
|
item.startDate = new Date(item.startDate.setHours(0, 0, 0, 0));
|
|
item.endDate = item.startDate;
|
|
}
|
|
return item;
|
|
}) || [];
|
|
|
|
await createEventsFromProvider(items);
|
|
} catch (error) {
|
|
console.error("Error fetching Google Calendar events:", error);
|
|
|
|
if (!isRetry) {
|
|
const refreshedToken = await handleRefreshToken(email, refreshToken);
|
|
if (refreshedToken) {
|
|
await updateUserData({
|
|
newUserData: {
|
|
googleAccounts: {
|
|
...profileData.googleAccounts,
|
|
[email!]: { ...profileData.googleAccounts[email!], accessToken: refreshedToken },
|
|
},
|
|
},
|
|
});
|
|
return tryFetchEvents(true); // Retry once after refreshing
|
|
} else {
|
|
await clearToken({ email: email!, provider: "google" });
|
|
console.error(`Token refresh failed; token cleared for ${email}`);
|
|
throw error;
|
|
}
|
|
} else {
|
|
console.error(`Retry failed after refreshing token for user ${profileData?.email}:`, error.message);
|
|
throw error;
|
|
}
|
|
}
|
|
};
|
|
|
|
return tryFetchEvents();
|
|
},
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries(["events"]);
|
|
},
|
|
});
|
|
};
|
|
|
|
async function handleRefreshToken(email: string, refreshToken: string) {
|
|
if (!refreshToken) return null;
|
|
|
|
try {
|
|
const response = await fetch('https://oauth2.googleapis.com/token', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
grant_type: 'refresh_token',
|
|
refresh_token: refreshToken,
|
|
client_id: "406146460310-2u67ab2nbhu23trp8auho1fq4om29fc0.apps.googleusercontent.com",
|
|
}),
|
|
});
|
|
|
|
const data = await response.json();
|
|
return data.access_token;
|
|
} catch (error) {
|
|
console.error("Error refreshing Google token:", error);
|
|
return null;
|
|
}
|
|
} |