Account deactivated
Your account has been deactivated. Please contact an administrator.
import { useAuth } from "@tailor-platform/app-shell"; import { useEffect, useRef, type ReactNode } from "react"; import { useQuery } from "urql"; import { graphql } from "@/graphql"; import { ConnectivityErrorScreen } from "./connectivity-error-screen"; import { Spinner } from "./ui/spinner"; const MeStatusQuery = graphql(` query MeStatus { me { status } } `); /** * Gates the app on the current user's account status. Runs after AuthGuard has * confirmed the user is authenticated. * * Decision matrix: * - auth error (UNAUTHORIZED/FORBIDDEN) -> token is invalid/expired, re-login * - query in flight -> spinner * - status ACTIVE -> render the app * - status confirmed but not ACTIVE -> "Account deactivated" * - indeterminate (network/server error or empty response) -> connectivity * error screen with a retry * * The "Account deactivated" screen is only ever shown for a *confirmed* * non-ACTIVE status — never as a side effect of missing data — so transient * connectivity failures are no longer misreported as a deactivated account. */ export const ActiveUserGuard = ({ children }: { children: ReactNode }) => { const { logout, login } = useAuth(); const [{ data, fetching, error }, refetch] = useQuery({ query: MeStatusQuery, }); // An auth error (UNAUTHORIZED/FORBIDDEN) means the token is invalid or // expired. Detect it whenever an error is present — even if we still hold // cached data from a previous fetch (urql is configured cache-and-network) — // so a revalidation auth failure still forces re-login instead of rendering // the app with a bad token. const isAuthError = error?.graphQLErrors?.some( (e) => e.extensions?.code === "UNAUTHORIZED" || e.extensions?.code === "FORBIDDEN", ) ?? false; // Trigger login as a post-render side effect, guarding against repeated calls // across re-renders. const loginStarted = useRef(false); useEffect(() => { if (isAuthError && !loginStarted.current) { loginStarted.current = true; void login(); } else if (!isAuthError) { loginStarted.current = false; } }, [isAuthError, login]); // Auth errors take precedence over every branch below: hold a blank frame // while the login redirect kicks in. if (isAuthError) return null; // Initial load or an in-flight retry without cached data -> show a spinner // instead of a blank screen so the user gets feedback that something is // happening. The `!data?.me` guard matters under urql's cache-and-network // policy: a re-execution or remount sets `fetching=true` while the previous // result is still in cache, and we don't want to flash a full-screen spinner // over the already-rendered app. if (fetching && !data?.me) { return (
Your account has been deactivated. Please contact an administrator.