Skip to content

Commit

Permalink
slow network message for api calls and timeout aborts. fixes missing …
Browse files Browse the repository at this point in the history
…context on YoID opportunity pages. (#749)
  • Loading branch information
jasondicker authored Apr 23, 2024
1 parent 17798d2 commit 3c7eeb5
Show file tree
Hide file tree
Showing 11 changed files with 112 additions and 32 deletions.
9 changes: 7 additions & 2 deletions src/web/src/api/services/user.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import ApiClient from "~/lib/axiosClient";
import type { UserProfile, UserRequestProfile } from "../models/user";
import type { GetServerSidePropsContext, GetStaticPropsContext } from "next";
import ApiServer from "~/lib/axiosServer";

export const patchUser = async (
model: UserRequestProfile,
Expand All @@ -8,8 +10,11 @@ export const patchUser = async (
return data;
};

export const getUserProfile = async (): Promise<UserProfile> => {
const { data } = await (await ApiClient).get<UserProfile>(`/user`);
export const getUserProfile = async (
context?: GetServerSidePropsContext | GetStaticPropsContext,
): Promise<UserProfile> => {
const instance = context ? ApiServer(context) : await ApiClient;
const { data } = await instance.get<UserProfile>(`/user`);
return data;
};

Expand Down
1 change: 0 additions & 1 deletion src/web/src/components/Layout/YoIDTabbed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import { AvatarImage } from "../AvatarImage";
import { IoIosInformationCircleOutline } from "react-icons/io";
import { ZltoModal } from "../Modals/ZltoModal";
import stamps from "public/images/stamps.svg";
// import iconShare from "public/images/icon-share.png";

export type TabProps = ({
children,
Expand Down
58 changes: 58 additions & 0 deletions src/web/src/lib/axiosClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,18 @@ import { type Session } from "next-auth";
import { getSession } from "next-auth/react";
import { fetchClientEnv } from "./utils";
import NProgress from "nprogress";
import { toast } from "react-toastify";
import {
SLOW_NETWORK_ABORT_TIMEOUT,
SLOW_NETWORK_MESSAGE_TIMEOUT,
} from "./constants";

let apiBaseUrl = "";

// state for slow network messages
let slowNetworkMessageDismissed = false;
let slowNetworkAbortDismissed = false;

// Axios instance for client-side requests
const ApiClient = async () => {
if (!apiBaseUrl) {
Expand All @@ -15,6 +24,8 @@ const ApiClient = async () => {
}
const instance = axios.create({
baseURL: apiBaseUrl,
timeout: SLOW_NETWORK_ABORT_TIMEOUT,
timeoutErrorMessage: "Network is slow. Please check your connection.",
});

let lastSession: Session | null = null;
Expand Down Expand Up @@ -44,16 +55,63 @@ const ApiClient = async () => {
//* Intercept requests/responses for NProgress
instance.interceptors.request.use((config) => {
NProgress.start();

// Start a timeout that will show a "slow network" message after timeout
if (!slowNetworkMessageDismissed) {
const timeoutId = setTimeout(() => {
toast.warn(
"Your request is taking longer than usual. Please check your connection.",
{
toastId: "network-slow",
autoClose: 3000,
onClick: () => {
slowNetworkMessageDismissed = true;
toast.dismiss("network-slow");
},
},
);
}, SLOW_NETWORK_MESSAGE_TIMEOUT);

// Attach the timeoutId to the config so we can access it in the response interceptor
(config as any).timeoutId = timeoutId;
}

return config;
});

instance.interceptors.response.use(
(response) => {
NProgress.done();

// Clear the timeout when the request completes
if ((response.config as any).timeoutId) {
clearTimeout((response.config as any).timeoutId);
}

return response;
},
(error) => {
NProgress.done();

// Clear the timeout when the request fails
if (error.config.timeoutId) {
clearTimeout(error.config.timeoutId);
}

if (
error.code === "ECONNABORTED" &&
slowNetworkAbortDismissed === false
) {
toast.error("Network is slow. Please check your connection.", {
toastId: "network-slow-error",
autoClose: false,
onClick: () => {
slowNetworkAbortDismissed = true;
toast.dismiss("network-slow-error");
},
});
}

return Promise.reject(error);
},
);
Expand Down
2 changes: 2 additions & 0 deletions src/web/src/lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,5 @@ export const VIEWPORT_SIZE = {

export const COUNTRY_WW = "WW";
export const COOKIE_KEYCLOAK_SESSION = "KEYCLOAK_SESSION";
export const SLOW_NETWORK_MESSAGE_TIMEOUT = 5000; // 5 seconds
export const SLOW_NETWORK_ABORT_TIMEOUT = 20000; // 20 seconds
1 change: 0 additions & 1 deletion src/web/src/pages/yoid/credentials/[[...query]].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import { IoMdCheckmark, IoMdClose } from "react-icons/io";
import ReactModal from "react-modal";
import { ApiErrors } from "~/components/Status/ApiErrors";
import { Unauthorized } from "~/components/Status/Unauthorized";
// import { LoadingSkeleton } from "~/components/Status/LoadingSkeleton";
import YoIDTabbed from "~/components/Layout/YoIDTabbed";
import { toast } from "react-toastify";
import { config } from "~/lib/react-query-config";
Expand Down
15 changes: 9 additions & 6 deletions src/web/src/pages/yoid/opportunities/completed/[[...query]].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,15 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
await queryClient.prefetchQuery({
queryKey: ["MyOpportunities_Completed", pageNumber],
queryFn: () =>
searchMyOpportunities({
action: Action.Verification,
verificationStatuses: [VerificationStatus.Completed],
pageNumber: pageNumber,
pageSize: PAGE_SIZE,
}),
searchMyOpportunities(
{
action: Action.Verification,
verificationStatuses: [VerificationStatus.Completed],
pageNumber: pageNumber,
pageSize: PAGE_SIZE,
},
context,
),
});

return {
Expand Down
15 changes: 9 additions & 6 deletions src/web/src/pages/yoid/opportunities/declined/[[...query]].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,15 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
await queryClient.prefetchQuery({
queryKey: ["MyOpportunities_Rejected", pageNumber],
queryFn: () =>
searchMyOpportunities({
action: Action.Verification,
verificationStatuses: [VerificationStatus.Rejected],
pageNumber: pageNumber,
pageSize: PAGE_SIZE,
}),
searchMyOpportunities(
{
action: Action.Verification,
verificationStatuses: [VerificationStatus.Rejected],
pageNumber: pageNumber,
pageSize: PAGE_SIZE,
},
context,
),
});

return {
Expand Down
15 changes: 9 additions & 6 deletions src/web/src/pages/yoid/opportunities/saved/[[...query]].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,15 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
await queryClient.prefetchQuery({
queryKey: ["MyOpportunities_Saved", pageNumber],
queryFn: () =>
searchMyOpportunities({
action: Action.Saved,
verificationStatuses: null,
pageNumber: pageNumber,
pageSize: PAGE_SIZE,
}),
searchMyOpportunities(
{
action: Action.Saved,
verificationStatuses: null,
pageNumber: pageNumber,
pageSize: PAGE_SIZE,
},
context,
),
});

return {
Expand Down
15 changes: 9 additions & 6 deletions src/web/src/pages/yoid/opportunities/submitted/[[...query]].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,15 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
await queryClient.prefetchQuery({
queryKey: ["MyOpportunities_Pending", pageNumber],
queryFn: () =>
searchMyOpportunities({
action: Action.Verification,
verificationStatuses: [VerificationStatus.Pending],
pageNumber: pageNumber,
pageSize: PAGE_SIZE,
}),
searchMyOpportunities(
{
action: Action.Verification,
verificationStatuses: [VerificationStatus.Pending],
pageNumber: pageNumber,
pageSize: PAGE_SIZE,
},
context,
),
});

return {
Expand Down
8 changes: 4 additions & 4 deletions src/web/src/pages/yoid/settings/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,19 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
await Promise.all([
await queryClient.prefetchQuery({
queryKey: ["genders"],
queryFn: async () => await getGenders(),
queryFn: async () => await getGenders(context),
}),
await queryClient.prefetchQuery({
queryKey: ["countries"],
queryFn: async () => await getCountries(),
queryFn: async () => await getCountries(context),
}),
await queryClient.prefetchQuery({
queryKey: ["educations"],
queryFn: async () => await getEducations(),
queryFn: async () => await getEducations(context),
}),
await queryClient.prefetchQuery({
queryKey: ["userProfile"],
queryFn: async () => await getUserProfile(),
queryFn: async () => await getUserProfile(context),
}),
]);

Expand Down
5 changes: 5 additions & 0 deletions src/web/src/styles/globals.scss
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ body {
}
}

// NProgress
#nprogress .bar {
height: 4px !important;
}

// override the NProgress styles based on the theme
[data-theme="purple"] #nprogress .bar {
@apply bg-blue;
Expand Down

0 comments on commit 3c7eeb5

Please sign in to comment.