Skip to content

Commit

Permalink
fea: new revalidation
Browse files Browse the repository at this point in the history
  • Loading branch information
Rahuletto committed Sep 14, 2024
1 parent 001494b commit 5e44146
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 23 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from "react";
import { useAttendance } from "@/provider/AttendanceProvider";
import Error from "@/components/States/Error";
import Loading from "@/components/States/Loading";
import NoData from "../NoData";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import PredictResetButtons from "./Predict/ResetButtons";
import InfoPopup from "./InfoPopup";
import { DateRange } from "@/types/Attendance";
import { DateObject } from "react-multi-date-picker";
import { useAttendance } from "@/provider/AttendanceProvider";
import { useData } from "@/provider/DataProvider";

interface AttendanceHeaderProps {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import React, { useEffect } from "react";
import { useAttendance } from "@/provider/AttendanceProvider";
import { useCalendar } from "@/provider/CalendarProvider";
import { useTimetable } from "@/provider/TimetableProvider";
import { useAttendancePrediction } from "@/hooks/useAttendancePredict";
import Error from "@/components/States/Error";
import Loading from "@/components/States/Loading";
Expand Down
1 change: 0 additions & 1 deletion hooks/useMutate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { token } from "@/utils/Encrypt";
import { getUrl, revalUrl } from "@/utils/URL";
import { useSWRConfig } from "swr";
import { Cookie as cookies } from "@/utils/Cookies";
import { useUser } from "@/provider/UserProvider";
import { useData } from "@/provider/DataProvider";

export interface MutateOptions {
Expand Down
33 changes: 16 additions & 17 deletions provider/AttendanceProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,19 @@ const fetcher = async (url: string) => {
return null;
else
try {
const response = await fetch(
getUrl() + "/attendance",
{
method: "GET",
headers: {
Authorization: `Bearer ${token()}`,
"X-CSRF-Token": cookie,
"Set-Cookie": cookie,
Cookie: cookie,
Connection: "keep-alive",
"Accept-Encoding": "gzip, deflate, br, zstd",
"content-type": "application/json",
"Cache-Control":
"private, maxage=86400, stale-while-revalidate=7200",
},
const response = await fetch(getUrl() + "/attendance", {
method: "GET",
headers: {
Authorization: `Bearer ${token()}`,
"X-CSRF-Token": cookie,
"Set-Cookie": cookie,
Cookie: cookie,
Connection: "keep-alive",
"Accept-Encoding": "gzip, deflate, br, zstd",
"content-type": "application/json",
"Cache-Control": "private, maxage=86400, stale-while-revalidate=7200",
},
);
});
if (!response.ok) {
const errorBody = await response.text();
throw new Error(
Expand Down Expand Up @@ -133,7 +129,10 @@ export function AttendanceProvider({
attendance: attendance?.attendance || null,
requestedAt: attendance?.requestedAt || 0,
error: error || null,
isOld: !isValidating && !error && attendance?.requestedAt ? Date.now() - attendance?.requestedAt > 2 * 60 * 60 * 1000 : false,
isOld:
!isValidating && !error && attendance?.requestedAt
? Date.now() - attendance?.requestedAt > 2 * 60 * 60 * 1000
: false,
isLoading: isValidating,
mutate,
}}
Expand Down
147 changes: 147 additions & 0 deletions provider/DataProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
"use client";
import { Cookie as cookies, getCookie } from "@/utils/Cookies";
import { type ReactNode, createContext, useContext, useState } from "react";
import useSWR from "swr";
import Storage from "@/utils/Storage";
import { AttendanceCourse } from "@/types/Attendance";
import { getUrl, revalUrl } from "@/utils/URL";
import { token } from "@/utils/Encrypt";
import { Mark } from "@/types/Marks";
import { Course } from "@/types/Course";
import { User } from "@/types/User";
import { Table } from "@/types/Timetable";
import { AllResponses } from "@/types/Response";

interface DataContextType {
attendance: AttendanceCourse[] | null;
marks: Mark[] | null;
courses: Course[] | null;
user: User | null;
timetable: Table[] | null;
error: Error | null;
requestedAt: number | null;
isLoading: boolean;
mutate: () => Promise<void | AllResponses | null | undefined>;
}

const DataContext = createContext<DataContextType>({
attendance: null,
marks: null,
courses: null,
user: null,
timetable: null,
error: null,
requestedAt: null,
isLoading: false,
mutate: async () => {},
});

const fetcher = async (url: string) => {
const cookie = cookies.get("key");
if (!cookie) return null;

const cook = getCookie(cookie ?? "", "_iamadt_client_10002227248");
if (
!cook ||
cook === "" ||
cook === "undefined" ||
cookie.includes("undefined")
)
return null;
else
try {
const response = await fetch(url, {
method: "GET",
headers: {
Authorization: `Bearer ${token()}`,
"X-CSRF-Token": cookie,
"Set-Cookie": cookie,
Cookie: cookie,
Connection: "keep-alive",
"Accept-Encoding": "gzip, deflate, br, zstd",
"content-type": "application/json",
"Cache-Control": "private, maxage=86400, stale-while-revalidate=7200",
},
});
if (!response.ok) {
const errorBody = await response.text();
throw new Error(
`HTTP error! status: ${response.status}, body: ${errorBody}`,
);
}

const data: AllResponses = await response.json();
if (
!data ||
!data.user ||
!data.attendance ||
!data.marks ||
!data.courses ||
!data.timetable
) {
throw new Error("Invalid response format");
}

return data;
} catch (error) {
if (error instanceof Error) {
throw error;
}
throw new Error("An unexpected error occurred");
}
};

export function useData() {
return useContext(DataContext);
}

export function DataProvider({ children }: { children: ReactNode }) {
const cookie = cookies.get("key");

const {
data: data,
error,
isValidating,
mutate,
} = useSWR<AllResponses | null>(cookie ? `${revalUrl}/get` : null, fetcher, {
revalidateOnFocus: false,
revalidateOnReconnect: false,
keepPreviousData: true,
shouldRetryOnError: false,
errorRetryCount: 0,
revalidateIfStale: false,
dedupingInterval: 1000 * 60 * 3,
onErrorRetry: (error, key, config, revalidate, { retryCount }) => {
return;
},
onSuccess: (data) => {
if (data) {
Storage.set("attendance", data.attendance);
Storage.set("marks", data.marks);
Storage.set("courses", data.courses);
Storage.set("timetable", data.timetable);
}
return data;
},
});

return (
<DataContext.Provider
value={{
attendance: data?.attendance || null,
marks: data?.marks || null,
courses: data?.courses || null,
user: data?.user || null,
timetable: data?.timetable || null,

requestedAt: data?.requestedAt || 0,
error: error || null,

isLoading: isValidating,
mutate,
}}
>
{children}
</DataContext.Provider>
);
}
14 changes: 14 additions & 0 deletions types/Response.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { AttendanceCourse } from "./Attendance";
import { Course } from "./Course";
import { Mark } from "./Marks";
import { Table } from "./Timetable";
import { User } from "./User";

export interface AllResponses {
user: User;
attendance: AttendanceCourse[];
marks: Mark[];
timetable: Table[];
courses: Course[];
requestedAt: number
}
2 changes: 1 addition & 1 deletion utils/URL.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export function getUrl(key: string, endpoint: string) {
export function getUrl() {
const rand = Math.floor(Math.random() * 4) + 1;
switch (rand) {
case 1:
Expand Down

0 comments on commit 5e44146

Please sign in to comment.