Skip to content

Commit

Permalink
Merge pull request #181 from appKom/178
Browse files Browse the repository at this point in the history
Refactor fetching logic
  • Loading branch information
julian-ao authored Jul 24, 2024
2 parents 241ca39 + 04b42ed commit d057086
Show file tree
Hide file tree
Showing 11 changed files with 168 additions and 161 deletions.
23 changes: 23 additions & 0 deletions components/ErrorPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import Image from "next/image";
import { useTheme } from "../lib/hooks/useTheme";

const ErrorPage = () => {
const theme = useTheme();

const onlineLogoSrc =
theme === "dark" ? "/Online_hvit.svg" : "/Online_bla.svg";

return (
<div className="flex flex-col items-center justify-center h-full gap-10 bg-white dark:bg-gray-900">
<Image
src={onlineLogoSrc}
width={300}
height={100}
alt="Online logo"
/>
<div className="text-xl text-black dark:text-white">Det har skjedd en feil :(</div>
</div>
);
};

export default ErrorPage;
2 changes: 1 addition & 1 deletion components/applicantoverview/ApplicantsOverview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import ApplicantTable from "./ApplicantTable";
import ApplicantOverviewSkeleton from "./ApplicantOverviewSkeleton";

interface Props {
period: periodType | null;
period?: periodType | null;
committees?: string[] | null;
committee?: string;
includePreferences: boolean;
Expand Down
9 changes: 9 additions & 0 deletions lib/api/applicantApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { QueryFunctionContext } from '@tanstack/react-query';

export const fetchApplicantByPeriodAndId = async (context: QueryFunctionContext) => {
const periodId = context.queryKey[1];
const applicantId = context.queryKey[2];
return fetch(`/api/applicants/${periodId}/${applicantId}`).then(res =>
res.json()
);
}
8 changes: 8 additions & 0 deletions lib/api/periodApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { QueryFunctionContext } from '@tanstack/react-query';

export const fetchPeriodById = async (context: QueryFunctionContext) => {
const id = context.queryKey[1];
return fetch(`/api/periods/${id}`).then(res =>
res.json()
);
}
25 changes: 25 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@heroicons/react": "^2.1.3",
"@tailwindcss/forms": "^0.5.7",
"@tailwindcss/typography": "github:tailwindcss/typography",
"@tanstack/react-query": "^5.51.11",
"@types/mongodb": "^4.0.7",
"mongodb": "^6.1.0",
"next": "^12.3.4",
Expand Down
23 changes: 17 additions & 6 deletions pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ import Navbar from "../components/Navbar";
import Footer from "../components/Footer";
import LoadingPage from "../components/LoadingPage";
import Signature from "../lib/utils/Signature";
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

const queryClient = new QueryClient({
defaultOptions: { // TODO: go over default options
queries: {
staleTime: 1000 * 60 * 10,
},
},
});

const SessionHandler: React.FC<{ children: React.ReactNode }> = ({
children,
Expand Down Expand Up @@ -70,12 +79,14 @@ function MyApp({ Component, pageProps: { session, ...pageProps } }: any) {
</Head>
<div className="flex flex-col min-h-screen bg-white dark:text-white dark:bg-gray-900">
<SessionHandler>
<Toaster />
<Navbar />
<div className="flex-grow">
<Component {...pageProps} />
</div>
<Footer />
<QueryClientProvider client={queryClient}>
<Toaster />
<Navbar />
<div className="flex-grow">
<Component {...pageProps} />
</div>
<Footer />
</QueryClientProvider>
</SessionHandler>
</div>
</SessionProvider>
Expand Down
44 changes: 17 additions & 27 deletions pages/admin/[period-id]/index.tsx
Original file line number Diff line number Diff line change
@@ -1,44 +1,34 @@
import { useSession } from "next-auth/react";
import { useEffect, useState } from "react";
import router from "next/router";
import { applicantType, periodType } from "../../../lib/types/types";
import { periodType } from "../../../lib/types/types";
import NotFound from "../../404";
import ApplicantsOverview from "../../../components/applicantoverview/ApplicantsOverview";
import { useQuery } from '@tanstack/react-query';
import { fetchPeriodById } from "../../../lib/api/periodApi";
import LoadingPage from "../../../components/LoadingPage";
import ErrorPage from "../../../components/ErrorPage";

const Admin = () => {
const { data: session } = useSession();
const periodId = router.query["period-id"];

const [period, setPeriod] = useState<periodType | null>(null);
const [committees, setCommittees] = useState<string[] | null>(null);

useEffect(() => {
const fetchPeriod = async () => {
if (!session || session.user?.role !== "admin") {
return;
}
if (periodId === undefined) return;

try {
const response = await fetch(`/api/periods/${periodId}`);
const data = await response.json();
if (response.ok) {
setPeriod(data.period);
setCommittees(data.period.committees);
} else {
throw new Error(data.error || "Unknown error");
}
} catch (error) {
console.error("Error checking period:", error);
} finally {
}
};
const { data, isError, isLoading } = useQuery({
queryKey: ['periods', periodId],
queryFn: fetchPeriodById,
});

fetchPeriod();
}, [session?.user?.owId, periodId]);
useEffect(() => {
setPeriod(data?.period)
setCommittees(data?.period.committees)
}, [data, session?.user?.owId]);

if (!session || session.user?.role !== "admin") {
return <NotFound />;
}
if (session?.user?.role !== "admin") return <NotFound />;
if (isLoading) return <LoadingPage />;
if (isError) return <ErrorPage />;

return (
<ApplicantsOverview
Expand Down
98 changes: 27 additions & 71 deletions pages/application/[period-id].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ import ApplicantCard from "../../components/applicantoverview/ApplicantCard";
import LoadingPage from "../../components/LoadingPage";
import { formatDateNorwegian } from "../../lib/utils/dateUtils";
import PageTitle from "../../components/PageTitle";
import { useQuery } from "@tanstack/react-query";
import { fetchPeriodById } from "../../lib/api/periodApi";
import { fetchApplicantByPeriodAndId } from "../../lib/api/applicantApi";
import ErrorPage from "../../components/ErrorPage";

interface FetchedApplicationData {
exists: boolean;
Expand All @@ -26,14 +30,12 @@ const Application: NextPage = () => {
const { data: session } = useSession();
const router = useRouter();
const periodId = router.query["period-id"] as string;
const applicantId = session?.user?.owId;

const [hasAlreadySubmitted, setHasAlreadySubmitted] = useState(true);
const [periodExists, setPeriodExists] = useState(false);
const [fetchedApplicationData, setFetchedApplicationData] =
useState<FetchedApplicationData | null>(null);

const [activeTab, setActiveTab] = useState(0);
const [isLoading, setIsLoading] = useState(true);
const [applicationData, setApplicationData] = useState<
DeepPartial<applicantType>
>({
Expand All @@ -53,53 +55,31 @@ const Application: NextPage = () => {
const [period, setPeriod] = useState<periodType>();
const [isApplicationPeriodOver, setIsApplicationPeriodOver] = useState(false);

const { data: periodData, isError: periodIsError, isLoading: periodIsLoading } = useQuery({
queryKey: ['periods', periodId],
queryFn: fetchPeriodById,
});

const { data: applicantData, isError: applicantIsError, isLoading: applicantIsLoading } = useQuery({
queryKey: ['applicants', periodId, applicantId],
queryFn: fetchApplicantByPeriodAndId,
});

useEffect(() => {
if (!period) {
return;
}
if (!periodData) return;

setPeriod(periodData.period);
setPeriodExists(periodData.exists);

const currentDate = new Date().toISOString();
if (new Date(period.applicationPeriod.end) < new Date(currentDate)) {
if (new Date(periodData.period.applicationPeriod.end) < new Date(currentDate)) {
setIsApplicationPeriodOver(true);
}
}, [period]);
}, [periodData]);

useEffect(() => {
const checkPeriodAndApplicationStatus = async () => {
if (!periodId || !session?.user?.owId) return;

try {
const periodResponse = await fetch(`/api/periods/${periodId}`);
const periodData = await periodResponse.json();
if (periodResponse.ok) {
setPeriod(periodData.period);
setPeriodExists(periodData.exists);
fetchApplicationData();
} else {
throw new Error(periodData.error || "Unknown error");
}
} catch (error) {
console.error("Error checking period:", error);
}

try {
const applicationResponse = await fetch(
`/api/applicants/${periodId}/${session.user.owId}`
);
const applicationData = await applicationResponse.json();

if (!applicationResponse.ok) {
throw new Error(applicationData.error || "Unknown error");
}
} catch (error) {
console.error("Error checking application status:", error);
} finally {
setIsLoading(false);
}
};

checkPeriodAndApplicationStatus();
}, [session?.user?.owId, periodId]);
setHasAlreadySubmitted(applicantData?.exists);
}, [applicantData]);

const handleSubmitApplication = async () => {
if (!validateApplication(applicationData)) return;
Expand Down Expand Up @@ -135,31 +115,6 @@ const Application: NextPage = () => {
} else {
toast.error("Det skjedde en feil, vennligst prøv igjen");
}
} finally {
fetchApplicationData();
}
};

const fetchApplicationData = async () => {
if (!session?.user?.owId || !periodId) return;

try {
const response = await fetch(
`/api/applicants/${periodId}/${session.user.owId}`
);
const data = await response.json();
if (!data.exists) {
setHasAlreadySubmitted(false);
} else {
setFetchedApplicationData(data);
}

if (!response.ok) {
throw new Error(data.error || "Unknown error");
}
} catch (error) {
console.error("Error fetching application data:", error);
toast.error("Failed to fetch application data.");
}
};

Expand Down Expand Up @@ -190,7 +145,8 @@ const Application: NextPage = () => {
}
};

if (isLoading) return <LoadingPage />;
if (periodIsLoading || applicantIsLoading) return <LoadingPage />;
if (periodIsError || applicantIsError) return <ErrorPage />;

if (!periodExists) {
return (
Expand Down Expand Up @@ -224,10 +180,10 @@ const Application: NextPage = () => {
onClick={handleDeleteApplication}
/>
)}
{fetchedApplicationData && (
{applicantData && (
<div className="w-full max-w-md">
<ApplicantCard
applicant={fetchedApplicationData.application}
applicant={applicantData.application}
includePreferences={true}
/>
</div>
Expand Down
Loading

0 comments on commit d057086

Please sign in to comment.