Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redirect already created users to the dashboard #653

Merged
8 changes: 8 additions & 0 deletions src/apps/create-patron-user-info/CreatePatron.dev.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ export default {
defaultValue: "/Logout",
control: { type: "text" }
},
dashboardUrl: {
defaultValue: "/user/me/dashboard",
control: { type: "text" }
},
agencyConfig: {
defaultValue: '{ "id": "999999" }',
spaceo marked this conversation as resolved.
Show resolved Hide resolved
control: { type: "text" }
spaceo marked this conversation as resolved.
Show resolved Hide resolved
},
textNotificationsEnabledConfig: {
defaultValue: "1",
control: { type: "text" }
Expand Down
4 changes: 3 additions & 1 deletion src/apps/create-patron-user-info/CreatePatron.entry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import CreatePatron from "./CreatePatron";
import { getToken, hasToken } from "../../core/token";

interface CreatePatronConfigProps {
agencyConfig: string;
pincodeLengthMinConfig: string;
pincodeLengthMaxConfig: string;
blacklistedPickupBranchesConfig: string;
Expand All @@ -17,6 +18,7 @@ interface CreatePatronUrlProps {
redirectOnUserCreatedUrl: string;
fbsBaseUrl: string;
publizonBaseUrl: string;
dashboardUrl: string;
}

interface CreatePatronTextProps {
Expand Down Expand Up @@ -59,7 +61,7 @@ const CreatePatronEntry: FC<CreatePatronProps> = () => {
return null;
}

return <CreatePatron userToken={userToken} />;
return <CreatePatron />;
};

export default withConfig(withText(withUrls(CreatePatronEntry)));
66 changes: 44 additions & 22 deletions src/apps/create-patron-user-info/CreatePatron.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,55 @@
import React, { useState, FC, useEffect } from "react";
import UserInfo from "./UserInfo";
import { useUrls } from "../../core/utils/url";
import { useText } from "../../core/utils/text";
import { redirectTo } from "../../core/utils/helpers/url";
import { useConfig } from "../../core/utils/config";
import useUserInfo from "../../core/adgangsplatformen/useUserInfo";

interface CreatePatronProps {
userToken: string;
}

const CreatePatron: FC<CreatePatronProps> = ({ userToken }) => {
const CreatePatron: FC = () => {
const [cpr, setCpr] = useState<string | null>(null);
const { userinfoUrl } = useUrls();
const config = useConfig();
const t = useText();
const { dashboardUrl } = useUrls();

if (!userinfoUrl) {
throw new Error("userinfoUrl is not defined");
}
const { id: agencyId } = config<{
id: `${number}`;
}>("agencyConfig", {
transformer: "jsonParse"
});

// Fetch user info data.
const { data: userInfo, isLoading } = useUserInfo();

useEffect(() => {
fetch(String(userinfoUrl), {
method: "get",
headers: { Authorization: `Bearer ${userToken}` }
})
.then((response) => response.json())
.then((data) => {
if (data?.attributes?.cpr) {
setCpr(data.attributes.cpr);
}
});
}, [userToken, userinfoUrl]);

if (cpr === null) return null;
if (isLoading || !userInfo) {
return;
}

const {
attributes: { agencies, cpr: userCpr }
} = userInfo;

const userWasAlreadyCreated = agencies.some(
(agency) => agency.agencyId === agencyId
);

// If the user was already created, redirect to the dashboard.
if (userWasAlreadyCreated) {
redirectTo(dashboardUrl);
spaceo marked this conversation as resolved.
Show resolved Hide resolved
}

// Otherwise set the cpr so we can show the create patron form.
setCpr(String(userCpr));
}, [agencyId, dashboardUrl, isLoading, userInfo]);

if (isLoading) {
return <div>{t("loadingText")}</div>;
}

if (!cpr) {
return null;
}

return <UserInfo cpr={cpr} />;
};
Expand Down
7 changes: 5 additions & 2 deletions src/apps/material/material.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,12 @@ import MaterialHeader from "../../components/material/MaterialHeader";
import MaterialSkeleton from "../../components/material/MaterialSkeleton";
import DisclosureSummary from "../../components/Disclosures/DisclosureSummary";
import MaterialDisclosure from "./MaterialDisclosure";
import { isAnonymous, isBlocked } from "../../core/utils/helpers/user";
import {
isAnonymous,
isBlocked,
usePatronData
} from "../../core/utils/helpers/user";
import ReservationFindOnShelfModals from "./ReservationFindOnShelfModals";
import { usePatronData } from "../../components/material/helper";

export interface MaterialProps {
wid: WorkId;
Expand Down
2 changes: 1 addition & 1 deletion src/apps/menu/menu-logged-in/MenuLoggedInContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ import {
import { useConfig } from "../../../core/utils/config";
import { ThresholdType } from "../../../core/utils/types/threshold-type";
import { useText } from "../../../core/utils/text";
import { usePatronData } from "../../../components/material/helper";
import { getReadyForPickup } from "../../reservation-list/utils/helpers";
import { ReservationType } from "../../../core/utils/types/reservation-type";
import DashboardNotificationList from "../../dashboard/dashboard-notification-list/dashboard-notification-list";
import { usePatronData } from "../../../core/utils/helpers/user";

interface MenuLoggedInContentProps {
pageSize: number;
Expand Down
3 changes: 1 addition & 2 deletions src/apps/menu/menu.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import React, { FC } from "react";
import profileIcon from "@danskernesdigitalebibliotek/dpl-design-system/build/icons/basic/icon-profile.svg";
import MenuNotLoggedInContent from "./menu-not-logged-in/menu-not-logged-in";
import { isAnonymous } from "../../core/utils/helpers/user";
import { isAnonymous, usePatronData } from "../../core/utils/helpers/user";
import MenuLoggedIn from "./menu-logged-in/menu-logged-in";
import { useText } from "../../core/utils/text";
import { useModalButtonHandler } from "../../core/utils/modal";
import { getModalIds } from "../../core/utils/helpers/general";
import { usePatronData } from "../../components/material/helper";
import TextLineSkeleton from "../../components/skeletons/TextLineSkeleton";

interface MenuProps {
Expand Down
2 changes: 1 addition & 1 deletion src/apps/patron-page/PatronPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import StatusSection from "./sections/StatusSection";
import PauseReservation from "../reservation-list/modal/pause-reservation/pause-reservation";
import { getModalIds } from "../../core/utils/helpers/general";
import { useUrls } from "../../core/utils/url";
import { usePatronData } from "../../components/material/helper";
import { useNotificationMessage } from "../../core/utils/useNotificationMessage";
import { usePatronData } from "../../core/utils/helpers/user";

const PatronPage: FC = () => {
const queryClient = useQueryClient();
Expand Down
2 changes: 1 addition & 1 deletion src/apps/reservation-list/list/reservation-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import ReservationDetails from "../modal/reservation-details/reservation-details
import { getUrlQueryParam } from "../../../core/utils/helpers/url";
import { getDetailsModalId } from "../../../core/utils/helpers/modal-helpers";
import { getFromListByKey } from "../../loan-list/utils/helpers";
import { usePatronData } from "../../../components/material/helper";
import { usePatronData } from "../../../core/utils/helpers/user";

export interface ReservationListProps {
pageSize: number;
Expand Down
3 changes: 1 addition & 2 deletions src/components/material/digital-modal/DigitalModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import { Pid, WorkId } from "../../../core/utils/types/ids";
import DigitalModalBody from "./DigitalModalBody";
import DigitalModalFeedback from "./DigitalModalFeedback";
import { createDigitalModalId, getResponseMessage } from "./helper";
import { isAnonymous } from "../../../core/utils/helpers/user";
import { usePatronData } from "../helper";
import { isAnonymous, usePatronData } from "../../../core/utils/helpers/user";

type DigitalModalProps = {
pid: Pid;
Expand Down
12 changes: 0 additions & 12 deletions src/components/material/helper.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/components/material/infomedia/InfomediaModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Pid } from "../../../core/utils/types/ids";
import InfomediaModalBody from "./InfomediaModalBody";
import { Manifestation } from "../../../core/utils/types/entities";
import InfomediaSkeleton from "./InfomediaSkeleton";
import { usePatronData } from "../helper";
import { usePatronData } from "../../../core/utils/helpers/user";

export const infomediaModalId = (pid: Pid) => `infomedia-modal-${pid}`;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import { Button } from "../../../Buttons/Button";
import { createDigitalModalId } from "../../digital-modal/helper";
import MaterialButtonLoading from "../generic/MaterialButtonLoading";
import MaterialButtonDisabled from "../generic/MaterialButtonDisabled";
import { usePatronData } from "../../helper";
import { isResident } from "../../../../core/utils/helpers/user";
import { isResident, usePatronData } from "../../../../core/utils/helpers/user";

export interface MaterialButtonOnlineDigitalArticleProps {
pid: Pid;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ import { Manifestation } from "../../../../core/utils/types/entities";
import { useUrls } from "../../../../core/utils/url";
import { Button } from "../../../Buttons/Button";
import { infomediaModalId } from "../../infomedia/InfomediaModal";
import { isResident } from "../../../../core/utils/helpers/user";
import { isResident, usePatronData } from "../../../../core/utils/helpers/user";
import MaterialButtonLoading from "../generic/MaterialButtonLoading";
import MaterialButtonDisabled from "../generic/MaterialButtonDisabled";
import { usePatronData } from "../../helper";

export interface MaterialButtonOnlineInfomediaArticleProps {
size?: ButtonSize;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
getManifestationType,
getReservablePidsFromAnotherLibrary
} from "../../../../core/utils/helpers/general";
import { isBlocked } from "../../../../core/utils/helpers/user";
import { isBlocked, usePatronData } from "../../../../core/utils/helpers/user";
import { ButtonSize } from "../../../../core/utils/types/button";
import { Manifestation } from "../../../../core/utils/types/entities";
import UseReservableManifestations from "../../../../core/utils/UseReservableManifestations";
Expand All @@ -13,7 +13,6 @@ import MaterialButtonReservePhysical from "./MaterialButtonPhysical";
import MaterialButtonLoading from "../generic/MaterialButtonLoading";
import MaterialButtonDisabled from "../generic/MaterialButtonDisabled";
import { useText } from "../../../../core/utils/text";
import { usePatronData } from "../../helper";
import MaterialButtonReservableFromAnotherLibrary from "./MaterialButtonReservableFromAnotherLibrary";

export interface MaterialButtonsPhysicalProps {
Expand Down
2 changes: 1 addition & 1 deletion src/components/reservation/ReservationModalBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,13 @@ import PromoBar from "../promo-bar/PromoBar";
import InstantLoan from "../instant-loan/InstantLoan";
import { excludeBlacklistedBranches } from "../../core/utils/branches";
import { InstantLoanConfigType } from "../../core/utils/types/instant-loan";
import { usePatronData } from "../material/helper";
import {
OpenOrderMutation,
useOpenOrderMutation
} from "../../core/dbc-gateway/generated/graphql";
import ModalMessage from "../message/modal-message/ModalMessage";
import configuration, { getConf } from "../../core/configuration";
import { usePatronData } from "../../core/utils/helpers/user";

type ReservationModalProps = {
selectedManifestations: Manifestation[];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import FetcherCriticalHttpError from "../fetchers/FetcherCriticalHttpError";
// This HttpError is critical because data such as fetching user data
// is crucial for the functioning of the application.
export default class AdgangsPlatformenServiceHttpError<
ContextType
> extends FetcherCriticalHttpError<ContextType> {
public readonly name = "AdgangsPlatformenServiceHttpError";
}
69 changes: 69 additions & 0 deletions src/core/adgangsplatformen/fetcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import FetchFailedCriticalError from "../fetchers/FetchFailedCriticalError";
import { getToken, TOKEN_USER_KEY } from "../token";
import AdgangsPlatformenServiceHttpError from "./AdgangsPlatformenServiceHttpError";

export const fetcher = async <ResponseType>({
url,
method,
headers,
data
}: {
url: string;
method: "get" | "post" | "put" | "delete" | "patch" | "head";
headers?: object;
data?: BodyType<unknown>;
signal?: AbortSignal;
}) => {
const userToken = getToken(TOKEN_USER_KEY);
if (!userToken) {
throw new Error("User token is missing");
}

const authHeaders = userToken
? ({ Authorization: `Bearer ${userToken}` } as object)
: {};

const body = data ? JSON.stringify(data) : null;

try {
const response = await fetch(url, {
method,
headers: {
...headers,
...authHeaders
},
body
});

if (!response.ok) {
throw new AdgangsPlatformenServiceHttpError(
response.status,
response.statusText,
url
);
}

try {
return (await response.json()) as ResponseType;
} catch (e) {
if (!(e instanceof SyntaxError)) {
throw e;
}
}
} catch (error: unknown) {
if (error instanceof AdgangsPlatformenServiceHttpError) {
throw error;
}

const message = error instanceof Error ? error.message : "Unknown error";
throw new FetchFailedCriticalError(message, url);
}

return null;
};

export default {};

export type ErrorType<ErrorData> = ErrorData;

export type BodyType<BodyData> = BodyData;
Loading
Loading