Show registration unavailable page when signup is disabled

Instead of showing the signup form and returning an internal error on
submit, the SignUpPage now queries signUpEnabled upfront and displays a
friendly message explaining that registration is not available, with a
link back to login.

Adds a signUpEnabled GraphQL query field on the connect/v1 API and
handles ErrSignupDisabled as a FORBIDDEN error in the SignUp resolver.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Sacha Al Himdani
2026-04-08 18:29:36 +02:00
parent ab5f42ad74
commit 76f6c8f9d1
4 changed files with 64 additions and 2 deletions

View File

@@ -16,14 +16,22 @@ import { formatError } from "@probo/helpers";
import { usePageTitle } from "@probo/hooks";
import { useTranslate } from "@probo/i18n";
import { Button, Field, useToast } from "@probo/ui";
import { useMutation } from "react-relay";
import { useEffect } from "react";
import { useMutation, usePreloadedQuery, useQueryLoader } from "react-relay";
import { Link, useNavigate } from "react-router";
import { graphql } from "relay-runtime";
import { z } from "zod";
import type { SignUpPageMutation } from "#/__generated__/iam/SignUpPageMutation.graphql";
import type { SignUpPageQuery } from "#/__generated__/iam/SignUpPageQuery.graphql";
import { useFormWithSchema } from "#/hooks/useFormWithSchema";
const signUpPageQuery = graphql`
query SignUpPageQuery {
signUpEnabled
}
`;
const signUpMutation = graphql`
mutation SignUpPageMutation($input: SignUpInput!) {
signUp(input: $input) {
@@ -42,13 +50,15 @@ const schema = z.object({
type FormData = z.infer<typeof schema>;
export default function SignUpPage() {
function SignUpPageContent(props: { queryRef: NonNullable<ReturnType<typeof useQueryLoader<SignUpPageQuery>>[0]> }) {
const { __ } = useTranslate();
const { toast } = useToast();
const navigate = useNavigate();
usePageTitle(__("Sign up"));
const data = usePreloadedQuery<SignUpPageQuery>(signUpPageQuery, props.queryRef);
const { register, handleSubmit, formState } = useFormWithSchema(schema, {
defaultValues: {
email: "",
@@ -95,6 +105,29 @@ export default function SignUpPage() {
});
};
if (!data.signUpEnabled) {
return (
<div className="space-y-6 w-full max-w-md mx-auto pt-8 text-center">
<div className="space-y-2">
<h1 className="text-3xl font-bold">{__("Registration unavailable")}</h1>
<p className="text-txt-tertiary">
{__("New account registration is currently disabled. Please contact your administrator or reach out to Probo for assistance.")}
</p>
</div>
<div>
<Button
variant="secondary"
className="w-xs h-10 mx-auto"
to="/auth/login"
>
{__("Back to login")}
</Button>
</div>
</div>
);
}
return (
<div className="space-y-6 w-full max-w-md mx-auto pt-8">
<div className="space-y-2 text-center">
@@ -154,3 +187,15 @@ export default function SignUpPage() {
</div>
);
}
export default function SignUpPage() {
const [queryRef, loadQuery] = useQueryLoader<SignUpPageQuery>(signUpPageQuery);
useEffect(() => {
loadQuery({});
}, [loadQuery]);
if (!queryRef) return null;
return <SignUpPageContent queryRef={queryRef} />;
}