fix(webapp): hard-navigate after creating an organization (#4530)

This commit is contained in:
claude[bot]
2026-08-11 16:00:06 +01:00
committed by GitHub
parent 336f515001
commit 8819e25751
2 changed files with 36 additions and 8 deletions
@@ -0,0 +1,6 @@
---
area: webapp
type: fix
---
Creating an organization sometimes left you back on the creation form even though the organization had already been created, so clicking Create again made a duplicate. Creating an organization now completes and takes you to your new organization.
+30 -8
View File
@@ -3,7 +3,12 @@ import { GlobeLinesIcon } from "~/assets/icons/GlobeLinesIcon";
import { parseWithZod } from "@conform-to/zod";
import { BuildingOffice2Icon } from "@heroicons/react/20/solid";
import { RadioGroup } from "@radix-ui/react-radio-group";
import { json, redirect, type ActionFunction, type LoaderFunctionArgs } from "@remix-run/node";
import {
json,
redirectDocument,
type ActionFunctionArgs,
type LoaderFunctionArgs,
} from "@remix-run/node";
import { Form, useActionData, useNavigation } from "@remix-run/react";
import { useState } from "react";
import { typedjson, useTypedLoaderData } from "remix-typedjson";
@@ -24,6 +29,7 @@ import { useFaviconUrl } from "~/hooks/useFaviconUrl";
import { useFeatures } from "~/hooks/useFeatures";
import { createOrganization } from "~/models/organization.server";
import { NewOrganizationPresenter } from "~/presenters/NewOrganizationPresenter.server";
import { logger } from "~/services/logger.server";
import { requireUser, requireUserId } from "~/services/session.server";
import { extractDomain, faviconUrl } from "~/utils/favicon";
import { organizationPath, rootPath } from "~/utils/pathBuilder";
@@ -47,7 +53,7 @@ export const loader = async ({ request }: LoaderFunctionArgs) => {
});
};
export const action: ActionFunction = async ({ request }) => {
export const action = async ({ request }: ActionFunctionArgs) => {
const user = await requireUser(request);
const formData = await request.formData();
const submission = parseWithZod(formData, { schema });
@@ -102,18 +108,32 @@ export const action: ActionFunction = async ({ request }) => {
if (next) {
params.set("next", next);
}
return redirect(`${organizationPath(organization)}/projects/new?${params.toString()}`);
return redirectDocument(
`${organizationPath(organization)}/projects/new?${params.toString()}`
);
}
return redirect(organizationPath(organization));
} catch (error: any) {
return json({ errors: { body: error.message } }, { status: 400 });
return redirectDocument(organizationPath(organization));
} catch (error) {
logger.error("Failed to create organization", {
userId: user.id,
error: error instanceof Error ? error.message : error,
});
return json(
submission.reply({
formErrors: [
"We couldn't create your organization. Check your organization list before trying again, and if this problem persists please contact support.",
],
}),
{ status: 400 }
);
}
};
export default function NewOrganizationPage() {
const { hasOrganizations } = useTypedLoaderData<typeof loader>();
const lastSubmission = useActionData();
const lastSubmission = useActionData<typeof action>();
const { isManagedCloud } = useFeatures();
const navigation = useNavigation();
const [companyUrl, setCompanyUrl] = useState("");
@@ -122,7 +142,7 @@ export default function NewOrganizationPage() {
const [form, { orgName }] = useForm({
id: "create-organization",
lastResult: lastSubmission as any,
lastResult: lastSubmission,
onValidate({ formData }) {
return parseWithZod(formData, { schema });
},
@@ -228,6 +248,8 @@ export default function NewOrganizationPage() {
</>
)}
<FormError id={form.errorId}>{form.errors}</FormError>
<FormButtons
confirmButton={
<Button type="submit" variant={"primary/small"} isLoading={isLoading}>