diff --git a/messages/en-US.json b/messages/en-US.json
index ca5557bc..e4b2999c 100644
--- a/messages/en-US.json
+++ b/messages/en-US.json
@@ -1725,5 +1725,6 @@
"healthCheckNotAvailable": "Local",
"rewritePath": "Rewrite Path",
"rewritePathDescription": "Optionally rewrite the path before forwarding to the target.",
- "continueToApplication": "Continue to application"
+ "continueToApplication": "Continue to application",
+ "checkingInvite": "Checking Invite"
}
diff --git a/src/app/invite/page.tsx b/src/app/invite/page.tsx
index 49c5a2c5..2e027f77 100644
--- a/src/app/invite/page.tsx
+++ b/src/app/invite/page.tsx
@@ -1,11 +1,6 @@
-import { internal } from "@app/lib/api";
-import { authCookieHeader } from "@app/lib/api/cookies";
import { verifySession } from "@app/lib/auth/verifySession";
-import { AcceptInviteResponse } from "@server/routers/user";
-import { AxiosResponse } from "axios";
import { redirect } from "next/navigation";
import InviteStatusCard from "../../components/InviteStatusCard";
-import { formatAxiosError } from "@app/lib/api";
import { getTranslations } from "next-intl/server";
export default async function InvitePage(props: {
@@ -27,8 +22,8 @@ export default async function InvitePage(props: {
if (parts.length !== 2) {
return (
<>
-
{t('inviteInvalid')}
- {t('inviteInvalidDescription')}
+ {t("inviteInvalid")}
+ {t("inviteInvalidDescription")}
>
);
}
@@ -36,58 +31,15 @@ export default async function InvitePage(props: {
const inviteId = parts[0];
const token = parts[1];
- let error = "";
- const res = await internal
- .post>(
- `/invite/accept`,
- {
- inviteId,
- token,
- },
- await authCookieHeader()
- )
- .catch((e) => {
- error = formatAxiosError(e);
- console.error(error);
- });
-
- if (res && res.status === 200) {
- redirect(`/${res.data.data.orgId}`);
- }
-
- function cardType() {
- if (error.includes("Invite is not for this user")) {
- return "wrong_user";
- } else if (
- error.includes("User does not exist. Please create an account first.")
- ) {
- return "user_does_not_exist";
- } else if (error.includes("You must be logged in to accept an invite")) {
- return "not_logged_in";
- } else {
- return "rejected";
- }
- }
-
- const type = cardType();
-
- if (!user && type === "user_does_not_exist") {
- const redirectUrl = emailParam
- ? `/auth/signup?redirect=/invite?token=${params.token}&email=${encodeURIComponent(emailParam)}`
- : `/auth/signup?redirect=/invite?token=${params.token}`;
- redirect(redirectUrl);
- }
-
- if (!user && type === "not_logged_in") {
- const redirectUrl = emailParam
- ? `/auth/login?redirect=/invite?token=${params.token}&email=${encodeURIComponent(emailParam)}`
- : `/auth/login?redirect=/invite?token=${params.token}`;
- redirect(redirectUrl);
- }
-
return (
<>
-
+
>
);
}
diff --git a/src/components/InviteStatusCard.tsx b/src/components/InviteStatusCard.tsx
index 6d7db4dc..d394bd57 100644
--- a/src/components/InviteStatusCard.tsx
+++ b/src/components/InviteStatusCard.tsx
@@ -1,47 +1,119 @@
"use client";
-import { createApiClient } from "@app/lib/api";
+import { createApiClient, formatAxiosError } from "@app/lib/api";
import { Button } from "@app/components/ui/button";
import {
Card,
CardContent,
CardFooter,
CardHeader,
- CardTitle,
+ CardTitle
} from "@app/components/ui/card";
import { useEnvContext } from "@app/hooks/useEnvContext";
-import { XCircle } from "lucide-react";
import { useRouter } from "next/navigation";
import { useTranslations } from "next-intl";
+import { useEffect, useState } from "react";
+import { AxiosResponse } from "axios";
+import { AcceptInviteResponse, GetUserResponse } from "@server/routers/user";
+import { Loader2 } from "lucide-react";
type InviteStatusCardProps = {
- type: "rejected" | "wrong_user" | "user_does_not_exist" | "not_logged_in";
- token: string;
+ user: GetUserResponse | null;
+ tokenParam: string;
+ inviteId: string;
+ inviteToken: string;
email?: string;
};
export default function InviteStatusCard({
- type,
- token,
+ inviteId,
email,
+ user,
+ tokenParam,
+ inviteToken
}: InviteStatusCardProps) {
const router = useRouter();
const api = createApiClient(useEnvContext());
const t = useTranslations();
+ const [loading, setLoading] = useState(true);
+ const [error, setError] = useState("");
+ const [type, setType] = useState<
+ "rejected" | "wrong_user" | "user_does_not_exist" | "not_logged_in"
+ >("rejected");
+
+ useEffect(() => {
+ async function init() {
+ let error = "";
+ const res = await api
+ .post>(`/invite/accept`, {
+ inviteId,
+ token: inviteToken
+ })
+ .catch((e) => {
+ error = formatAxiosError(e);
+ console.log("Error accepting invite:", error);
+ setError(error);
+ // console.error(e);
+ });
+
+ if (res && res.status === 200) {
+ router.push(`/${res.data.data.orgId}`);
+ return;
+ }
+
+ function cardType() {
+ if (error.includes("Invite is not for this user")) {
+ return "wrong_user";
+ } else if (
+ error.includes(
+ "User does not exist. Please create an account first."
+ )
+ ) {
+ return "user_does_not_exist";
+ } else if (
+ error.includes("You must be logged in to accept an invite")
+ ) {
+ return "not_logged_in";
+ } else {
+ return "rejected";
+ }
+ }
+
+ const type = cardType();
+ setType(type);
+
+ if (!user && type === "user_does_not_exist") {
+ const redirectUrl = email
+ ? `/auth/signup?redirect=/invite?token=${tokenParam}&email=${encodeURIComponent(email)}`
+ : `/auth/signup?redirect=/invite?token=${tokenParam}`;
+ router.push(redirectUrl);
+ } else if (!user && type === "not_logged_in") {
+ const redirectUrl = email
+ ? `/auth/login?redirect=/invite?token=${tokenParam}&email=${encodeURIComponent(email)}`
+ : `/auth/login?redirect=/invite?token=${tokenParam}`;
+ router.push(redirectUrl);
+ } else {
+ setLoading(false);
+ }
+ }
+
+ init();
+ }, []);
+
async function goToLogin() {
await api.post("/auth/logout", {});
- const redirectUrl = email
- ? `/auth/login?redirect=/invite?token=${token}&email=${encodeURIComponent(email)}`
- : `/auth/login?redirect=/invite?token=${token}`;
+ const redirectUrl = email
+ ? `/auth/login?redirect=/invite?token=${tokenParam}&email=${encodeURIComponent(email)}`
+ : `/auth/login?redirect=/invite?token=${tokenParam}`;
router.push(redirectUrl);
}
async function goToSignup() {
await api.post("/auth/logout", {});
- const redirectUrl = email
- ? `/auth/signup?redirect=/invite?token=${token}&email=${encodeURIComponent(email)}`
- : `/auth/signup?redirect=/invite?token=${token}`;
+ const redirectUrl = email
+ ? `/auth/signup?redirect=/invite?token=${tokenParam}&email=${encodeURIComponent(email)}`
+ : `/auth/signup?redirect=/invite?token=${tokenParam}`;
router.push(redirectUrl);
}
@@ -50,35 +122,27 @@ export default function InviteStatusCard({
return (
- {t('inviteErrorNotValid')}
+ {t("inviteErrorNotValid")}
- - {t('inviteErrorExpired')}
- - {t('inviteErrorRevoked')}
- - {t('inviteErrorTypo')}
+ - {t("inviteErrorExpired")}
+ - {t("inviteErrorRevoked")}
+ - {t("inviteErrorTypo")}
);
} else if (type === "wrong_user") {
return (
-
- {t('inviteErrorUser')}
-
-
- {t('inviteLoginUser')}
-
+
{t("inviteErrorUser")}
+
{t("inviteLoginUser")}
);
} else if (type === "user_does_not_exist") {
return (
-
- {t('inviteErrorNoUser')}
-
-
- {t('inviteCreateUser')}
-
+
{t("inviteErrorNoUser")}
+
{t("inviteCreateUser")}
);
}
@@ -92,37 +156,43 @@ export default function InviteStatusCard({
router.push("/");
}}
>
- {t('goHome')}
+ {t("goHome")}
);
} else if (type === "wrong_user") {
return (
-
+
);
} else if (type === "user_does_not_exist") {
- return ;
+ return ;
}
}
return (
-
+
- {/*
-
-
*/}
- {t('inviteNotAccepted')}
+ {loading ? t("checkingInvite") : t("inviteNotAccepted")}
- {renderBody()}
+
+ {loading && (
+
+ )}
+ {!loading && renderBody()}
+
-
- {renderFooter()}
-
+ {!loading && (
+
+ {renderFooter()}
+
+ )}
);