From 072b101624f8da2ea0f9fc54171963d0491ced1f Mon Sep 17 00:00:00 2001 From: Jake Howell Date: Tue, 28 Jul 2026 13:39:42 +1000 Subject: [PATCH] chore: setup page cleanup (#24649) This pull-request addresses a few things that may have made this page less accurate than we would have liked. * Disable the setup form when it is submitting things to the backend. * Migrate `` over to being backed by `` * Don't make use of `` in the header. Rely on the `font-semibold` as per other headings in the codebase. --- site/src/components/Input/Input.tsx | 2 +- .../PasswordField/PasswordField.tsx | 54 +++++-------------- site/src/pages/SetupPage/SetupPageView.tsx | 26 +++++++-- 3 files changed, 35 insertions(+), 47 deletions(-) diff --git a/site/src/components/Input/Input.tsx b/site/src/components/Input/Input.tsx index 944701d287..a72a27867b 100644 --- a/site/src/components/Input/Input.tsx +++ b/site/src/components/Input/Input.tsx @@ -5,7 +5,7 @@ import type { ComponentPropsWithRef, FC } from "react"; import { cn } from "#/utils/cn"; -export type InputProps = ComponentPropsWithRef<"input">; +type InputProps = ComponentPropsWithRef<"input">; export const Input: FC = ({ className, type, ...props }) => { return ( diff --git a/site/src/components/PasswordField/PasswordField.tsx b/site/src/components/PasswordField/PasswordField.tsx index c38d6b9972..0adf1a0e83 100644 --- a/site/src/components/PasswordField/PasswordField.tsx +++ b/site/src/components/PasswordField/PasswordField.tsx @@ -1,27 +1,17 @@ -import type { FC } from "react"; +import type { ComponentProps, FC } from "react"; import { keepPreviousData, useQuery } from "react-query"; import { API } from "#/api/api"; -import { Input, type InputProps } from "#/components/Input/Input"; -import { Label } from "#/components/Label/Label"; +import { FormField } from "#/components/FormField/FormField"; import { useDebouncedValue } from "#/hooks/debounce"; -import { cn } from "#/utils/cn"; -import type { FormHelpers } from "#/utils/formUtils"; -type PasswordFieldProps = InputProps & { - label: string; - field: FormHelpers; -}; +type PasswordFieldProps = ComponentProps; /** * A password field component that validates the password against the API with * debounced calls. It uses a debounced value to minimize the number of API * calls and displays validation errors. */ -export const PasswordField: FC = ({ - label, - field, - ...props -}) => { +export const PasswordField: FC = ({ field, ...props }) => { const value = field.value === undefined ? "" : String(field.value); const debouncedValue = useDebouncedValue(value, 500); const validatePasswordQuery = useQuery({ @@ -30,35 +20,17 @@ export const PasswordField: FC = ({ placeholderData: keepPreviousData, enabled: debouncedValue.length > 0, }); - const valid = validatePasswordQuery.data?.valid ?? true; - - const displayHelper = !valid - ? validatePasswordQuery.data?.details + const invalidPassword = validatePasswordQuery.data?.valid === false; + const helperText = invalidPassword + ? (validatePasswordQuery.data?.details ?? field.helperText) : field.helperText; + const mergedField = { + ...field, + error: field.error || invalidPassword, + helperText, + }; return ( -
- - - {displayHelper && ( - - {displayHelper} - - )} -
+ ); }; diff --git a/site/src/pages/SetupPage/SetupPageView.tsx b/site/src/pages/SetupPage/SetupPageView.tsx index 72a3b41c4b..2bd0a31c5f 100644 --- a/site/src/pages/SetupPage/SetupPageView.tsx +++ b/site/src/pages/SetupPage/SetupPageView.tsx @@ -114,6 +114,7 @@ type SelectFieldProps = FormHelpers & { onValueChange: (value: string) => void; placeholder?: string; children: ReactNode; + disabled?: boolean; }; const SelectField: FC = ({ @@ -126,6 +127,7 @@ const SelectField: FC = ({ onValueChange, placeholder, children, + disabled, }) => ( = ({ helperText={helperText} className={className} > - @@ -193,9 +199,7 @@ export const SetupPageView: FC = ({
-

- Welcome to Coder -

+

Welcome to Coder

Set up your admin account and start building secure, reproducible dev environments. @@ -229,13 +233,15 @@ export const SetupPageView: FC = ({ onChange={onChangeTrimmed(form, (email) => { form.setFieldValue("username", usernameFromEmail(email)); })} + disabled={isLoading} /> {/* Password */} {/* Premium trial toggle */} @@ -252,6 +258,7 @@ export const SetupPageView: FC = ({ } data-testid="trial" className="mt-0.5" + disabled={isLoading} />

@@ -279,10 +286,12 @@ export const SetupPageView: FC = ({
@@ -290,6 +299,7 @@ export const SetupPageView: FC = ({ = ({ form.setFieldValue("trial_info.developers", value) } placeholder="Select..." + disabled={isLoading} > {numberOfDevelopersOptions.map((opt) => ( @@ -309,12 +320,14 @@ export const SetupPageView: FC = ({
= ({ form.setFieldValue("trial_info.country", value) } placeholder="Select..." + disabled={isLoading} > {countries.map((c) => ( @@ -354,6 +368,7 @@ export const SetupPageView: FC = ({ ) } data-testid="onboarding_info.newsletter_releases" + disabled={isLoading} />
Release notes & updates @@ -379,6 +394,7 @@ export const SetupPageView: FC = ({ ) } data-testid="onboarding_info.newsletter_marketing" + disabled={isLoading} />
Monthly Coder newsletter