fix(companies): align optional numeric fields with API validation
continuous-integration/drone/push Build is passing
continuous-integration/drone/push Build is passing
Make employee_count, annual_revenue, and founded_year truly optional in the create company form and payload. Add field validation docs and Cypress e2e coverage for dashboard and notifications. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -25,6 +25,35 @@ const FieldError = ({ message }: { message?: string }) =>
|
||||
<p className="mt-1.5 text-sm font-medium text-error">{message}</p>
|
||||
) : null;
|
||||
|
||||
const optionalNumber = (value: unknown) => {
|
||||
if (value === "" || value === null || value === undefined) return undefined;
|
||||
return Number(value);
|
||||
};
|
||||
|
||||
const optionalNumberRange = ({
|
||||
min,
|
||||
max,
|
||||
integer = false,
|
||||
}: {
|
||||
min: number;
|
||||
max: number;
|
||||
integer?: boolean;
|
||||
}) => {
|
||||
return (value: unknown) => {
|
||||
const numberValue = optionalNumber(value);
|
||||
|
||||
if (numberValue === undefined) return true;
|
||||
if (!Number.isFinite(numberValue)) return "Enter a valid number";
|
||||
if (integer && !Number.isInteger(numberValue)) {
|
||||
return "This field must be a whole number";
|
||||
}
|
||||
if (numberValue < min) return FormErrorMessages.min(min);
|
||||
if (numberValue > max) return FormErrorMessages.max(max);
|
||||
|
||||
return true;
|
||||
};
|
||||
};
|
||||
|
||||
const CreateCompany = ({ defaultValues, editMode, id }: IProps) => {
|
||||
const {
|
||||
errors,
|
||||
@@ -223,8 +252,12 @@ const CreateCompany = ({ defaultValues, editMode, id }: IProps) => {
|
||||
>
|
||||
<InputGroup
|
||||
{...register("employee_count", {
|
||||
min: { value: 1, message: FormErrorMessages.min(1) },
|
||||
max: { value: 100000, message: FormErrorMessages.max(100000) },
|
||||
setValueAs: optionalNumber,
|
||||
validate: optionalNumberRange({
|
||||
min: 1,
|
||||
max: 100000,
|
||||
integer: true,
|
||||
}),
|
||||
})}
|
||||
errors={errors}
|
||||
label="Employee count"
|
||||
@@ -233,11 +266,11 @@ const CreateCompany = ({ defaultValues, editMode, id }: IProps) => {
|
||||
/>
|
||||
<InputGroup
|
||||
{...register("annual_revenue", {
|
||||
min: { value: 0, message: FormErrorMessages.min(0) },
|
||||
max: {
|
||||
value: 999999999999,
|
||||
message: FormErrorMessages.max(999999999999),
|
||||
},
|
||||
setValueAs: optionalNumber,
|
||||
validate: optionalNumberRange({
|
||||
min: 0,
|
||||
max: 999999999999,
|
||||
}),
|
||||
})}
|
||||
errors={errors}
|
||||
label="Annual revenue"
|
||||
@@ -246,8 +279,12 @@ const CreateCompany = ({ defaultValues, editMode, id }: IProps) => {
|
||||
/>
|
||||
<InputGroup
|
||||
{...register("founded_year", {
|
||||
min: { value: 1800, message: FormErrorMessages.min(1800) },
|
||||
max: { value: 2100, message: FormErrorMessages.max(2100) },
|
||||
setValueAs: optionalNumber,
|
||||
validate: optionalNumberRange({
|
||||
min: 1800,
|
||||
max: 2100,
|
||||
integer: true,
|
||||
}),
|
||||
})}
|
||||
errors={errors}
|
||||
label="Founded year"
|
||||
|
||||
@@ -46,12 +46,19 @@ const useCreateCompanyPresenter = ({ defaultValues, editMode, id }: IProps) => {
|
||||
const { mutate: updateCompany, isPending: isUpdating } = useUpdateCompany(
|
||||
id as string,
|
||||
);
|
||||
|
||||
const optionalNumber = (value: unknown) => {
|
||||
if (value === "" || value === null || value === undefined) return undefined;
|
||||
|
||||
return Number(value);
|
||||
};
|
||||
|
||||
const onSubmit: SubmitHandler<ICreateCompanyCredentials> = (data) => {
|
||||
const formattedData = {
|
||||
...data,
|
||||
founded_year: data.founded_year ? +data.founded_year : 0,
|
||||
employee_count: data.employee_count ? +data.employee_count : 0,
|
||||
annual_revenue: data.annual_revenue ? +data.annual_revenue : 0,
|
||||
founded_year: optionalNumber(data.founded_year),
|
||||
employee_count: optionalNumber(data.employee_count),
|
||||
annual_revenue: optionalNumber(data.annual_revenue),
|
||||
document_file_ids: data.document_file_ids ?? [],
|
||||
tags: {
|
||||
keywords: data?.tags?.keywords?.length ? data?.tags?.keywords : [],
|
||||
|
||||
@@ -35,9 +35,9 @@ export interface ICreateCompanyCredentials {
|
||||
website: string;
|
||||
type: string;
|
||||
description: string;
|
||||
founded_year: number;
|
||||
employee_count: number;
|
||||
annual_revenue: number;
|
||||
founded_year?: number | string;
|
||||
employee_count?: number | string;
|
||||
annual_revenue?: number | string;
|
||||
currency: string;
|
||||
industry: string;
|
||||
language: string;
|
||||
|
||||
@@ -35,9 +35,9 @@ export interface ICreateCompanyCredentials {
|
||||
website: string;
|
||||
type: string;
|
||||
description: string;
|
||||
founded_year: number;
|
||||
employee_count: number;
|
||||
annual_revenue: number;
|
||||
founded_year?: number | string;
|
||||
employee_count?: number | string;
|
||||
annual_revenue?: number | string;
|
||||
currency: string;
|
||||
industry: string;
|
||||
language: string;
|
||||
|
||||
Reference in New Issue
Block a user