PromucFlow_constructor/app/client/src/pages/setup/NonSuperUserProfilingQuestions.tsx
Jacques Ikot ed940a6413
fix: improve full name input styling to match radio buttons (#40727)
### Summary
This PR updates the styling of the user full name input field on the
onboarding screen to match the styling of the radio button groups,
creating a more consistent and polished UI.

### Problem
The full name input field in the onboarding form had inconsistent
styling compared to the radio button groups, which created a visually
disjointed user experience.

### Solution
- Created a styled version of `FormTextField` that matches the styling
of radio buttons
- Added proper spacing with a dedicated `InputSection` component
- Removed unnecessary vertical spacing elements
- Ensured consistent typography, sizing, and spacing across form
elements

### Changes
- Added `StyledFormTextField` with custom CSS to match radio button
styling:
  - Same font size and weight for labels
  - Consistent height, padding, and border-radius
  - Full width input field
- Created `InputSection` for consistent vertical spacing
- Replaced original `FormTextField` with the styled version
- Removed redundant `Space` components

### Screenshots
![Before](
<img width="1449" alt="Screenshot 2025-05-22 at 6 50 04 AM"
src="https://github.com/user-attachments/assets/54384e0d-4874-4550-8415-54b15a8e9b13"
/>
) | ![After](
<img width="1452" alt="Screenshot 2025-05-22 at 6 39 38 AM"
src="https://github.com/user-attachments/assets/01b8fd1e-0c47-4d8f-abe7-4f47a31366b6"
/>
)

## Automation

/ok-to-test tags="@tag.Sanity, @tag.Authentication"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/15205128744>
> Commit: 6e26d5ad7afef489697362b9202d7fd3be5b63a0
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=15205128744&attempt=1"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.Sanity, @tag.Authentication`
> Spec:
> <hr>Fri, 23 May 2025 08:33:29 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [ ] No


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added a required full name field to the non-super user profiling form,
displayed when cloud billing is enabled.
- **Style**
- Improved input field appearance and adjusted vertical spacing for a
cleaner form layout.
- **Refactor**
- Streamlined form styling by introducing new styled components and
localizing spacing definitions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-26 01:02:18 -07:00

161 lines
4.4 KiB
TypeScript

import React from "react";
import { Button } from "@appsmith/ads";
import {
WELCOME_FORM_USECASE_FIELD_NAME,
WELCOME_NON_SUPER_FORM_NAME,
WELCOME_FORM_PROFICIENCY_LEVEL,
} from "ee/constants/forms";
import {
createMessage,
WELCOME_ACTION,
WELCOME_FORM_NON_SUPER_USER_USE_CASE,
WELCOME_FORM_NON_SUPER_USER_PROFICIENCY_LEVEL,
WELCOME_FORM_PROFICIENCY_ERROR_MESSAGE,
WELCOME_FORM_USE_CASE_ERROR_MESSAGE,
WELCOME_FORM_FULL_NAME,
WELCOME_FORM_FULL_NAME_ERROR_MESSAGE,
} from "ee/constants/messages";
import { connect } from "react-redux";
import type { DefaultRootState } from "react-redux";
import type { InjectedFormProps } from "redux-form";
import { Field, formValueSelector, reduxForm } from "redux-form";
import styled from "styled-components";
import { proficiencyOptions, useCaseOptions } from "./constants";
import RadioButtonGroup from "components/editorComponents/RadioButtonGroup";
import FormTextField from "components/utils/ReduxFormTextField";
import { useIsCloudBillingEnabled } from "hooks";
const ActionContainer = styled.div`
margin-top: ${(props) => props.theme.spaces[15]}px;
`;
const StyledButton = styled(Button)`
margin-top: ${(props) => props.theme.spaces[3]}px;
width: 160px;
`;
const StyledFormTextField = styled(FormTextField)`
.ads-v2-input__input {
height: 36px;
border-radius: var(--ads-v2-border-radius);
padding: var(--ads-v2-spaces-3);
font-size: var(--ads-font-size-4);
width: 100%;
box-sizing: border-box;
}
.ads-v2-input__label {
font-size: var(--ads-font-size-4);
font-weight: var(--ads-font-weight-bold-xl);
color: var(--ads-v2-color-gray-700);
margin-bottom: 0.5rem;
}
`;
const InputSection = styled.div`
margin-bottom: ${(props) => props.theme.spaces[12]}px;
margin-top: ${(props) => props.theme.spaces[10]}px;
max-width: 505px;
`;
interface UserFormProps {
onGetStarted?: (proficiency?: string, useCase?: string) => void;
}
interface NonSuperUserFormData {
proficiency?: string;
useCase?: string;
fullName?: string;
}
export const Space = styled.div`
height: 20px;
`;
const validate = (values: NonSuperUserFormData) => {
const errors: Partial<NonSuperUserFormData> = {};
if (!values.proficiency) {
errors.proficiency = createMessage(WELCOME_FORM_PROFICIENCY_ERROR_MESSAGE);
}
if (!values.useCase) {
errors.useCase = createMessage(WELCOME_FORM_USE_CASE_ERROR_MESSAGE);
}
if (!values.fullName) {
errors.fullName = createMessage(WELCOME_FORM_FULL_NAME_ERROR_MESSAGE);
}
return errors;
};
function NonSuperUserProfilingQuestions(
props: InjectedFormProps & UserFormProps & NonSuperUserFormData,
) {
const isCloudBillingEnabled = useIsCloudBillingEnabled();
const onSubmit = (data: NonSuperUserFormData) => {
props.onGetStarted && props.onGetStarted(data.proficiency, data.useCase);
};
return (
<form onSubmit={props.handleSubmit(onSubmit)}>
{isCloudBillingEnabled && (
<InputSection>
<StyledFormTextField
data-testid="t--user-full-name"
label={createMessage(WELCOME_FORM_FULL_NAME)}
name="fullName"
placeholder="Enter your full name"
/>
</InputSection>
)}
<Space />
<Field
component={RadioButtonGroup}
label={createMessage(WELCOME_FORM_NON_SUPER_USER_PROFICIENCY_LEVEL)}
name="proficiency"
options={proficiencyOptions}
showSubtitle
testid="t--user-proficiency"
/>
<Space />
<Field
component={RadioButtonGroup}
label={createMessage(WELCOME_FORM_NON_SUPER_USER_USE_CASE)}
name="useCase"
options={useCaseOptions}
testid="t--user-use-case"
/>
<ActionContainer>
<StyledButton
className="w-full t--get-started-button"
isDisabled={props.invalid}
kind="primary"
renderAs="button"
size={"md"}
type="submit"
>
{createMessage(WELCOME_ACTION)}
</StyledButton>
</ActionContainer>
</form>
);
}
const selector = formValueSelector(WELCOME_NON_SUPER_FORM_NAME);
export default connect((state: DefaultRootState) => {
return {
proficiency: selector(state, WELCOME_FORM_PROFICIENCY_LEVEL),
useCase: selector(state, WELCOME_FORM_USECASE_FIELD_NAME),
};
}, null)(
reduxForm<NonSuperUserFormData, UserFormProps>({
validate,
form: WELCOME_NON_SUPER_FORM_NAME,
touchOnBlur: true,
})(NonSuperUserProfilingQuestions),
);