Skip to content

Commit 271e840

Browse files
authored
feat(review-step) - if initiated move to review step (#1003)
* feat(review-step) - if initiated move to review step * add tests * add test contractor onboarding * fix tests * remove canInvite * fix tests * update readme * format * fix invited status * fix invited
1 parent 6a239ca commit 271e840

10 files changed

Lines changed: 122 additions & 71 deletions

File tree

example/src/ReviewOnboardingStep.tsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,20 +167,17 @@ export const MyOnboardingInviteButton = ({
167167
creditRiskStatus,
168168
Component,
169169
setErrors,
170-
canInvite,
171170
}: {
172171
creditRiskStatus?: CreditRiskStatus;
173172
Component: React.ComponentType<OnboardingInviteProps>;
174173
setErrors: (errors: {
175174
apiError: string;
176175
fieldErrors: NormalizedFieldError[];
177176
}) => void;
178-
canInvite?: boolean;
179177
}) => {
180178
if (creditRiskStatus !== 'referred') {
181179
return (
182180
<Component
183-
disabled={!canInvite}
184181
className='submit-button'
185182
onSuccess={() => {
186183
console.log(
@@ -306,7 +303,6 @@ export const ReviewOnboardingStep = ({
306303
creditRiskStatus={creditRiskStatus}
307304
Component={OnboardingInvite}
308305
setErrors={setErrors}
309-
canInvite={onboardingBag.canInvite}
310306
/>
311307
</div>
312308
<AlertError errors={errors} />

src/flows/ContractorOnboarding/hooks.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,9 @@ export const useContractorOnboarding = ({
198198
!disabledInviteButtonEmploymentStatus.includes(employmentStatus);
199199

200200
const invitedStatus: 'invited' | 'not_invited' = useMemo(() => {
201-
const isInvited = employmentStatus === 'invited';
201+
const invitedStatuses = ['invited', 'initiated'];
202+
const isInvited =
203+
employmentStatus && invitedStatuses.includes(employmentStatus);
202204

203205
return isInvited ? 'invited' : 'not_invited';
204206
}, [employmentStatus]);

src/flows/ContractorOnboarding/tests/ContractorOnboarding.test.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,12 @@ describe('ContractorOnboardingFlow', () => {
752752
});
753753
});
754754

755-
it.each(['invited', 'created_awaiting_reserve', 'created_reserve_paid'])(
755+
it.each([
756+
'invited',
757+
'created_awaiting_reserve',
758+
'created_reserve_paid',
759+
'initiated',
760+
])(
756761
'should automatically navigate to review step when employment status is %s and display employment data',
757762
async (status) => {
758763
const employmentId = generateUniqueEmploymentId();

src/flows/ContractorOnboarding/tests/OnboardingInvite.test.tsx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,30 @@ describe('ContractorOnboarding - OnboardingInvite', () => {
167167
expect(button).toBeInTheDocument();
168168
});
169169

170+
it('should disable button when employment status is "initiated"', async () => {
171+
server.use(
172+
http.get('*/v1/employments/:id', ({ params }) => {
173+
const employmentId = params?.id;
174+
return HttpResponse.json({
175+
...mockContractorEmploymentResponse,
176+
data: {
177+
...mockContractorEmploymentResponse.data,
178+
employment: {
179+
...mockContractorEmploymentResponse.data.employment,
180+
status: 'initiated',
181+
id: employmentId,
182+
},
183+
},
184+
});
185+
}),
186+
);
187+
render(<ContractorOnboardingFlow {...defaultProps} />, {
188+
wrapper: TestProviders,
189+
});
190+
const button = await screen.findByText(/Invite Contractor/i);
191+
expect(button).toBeDisabled();
192+
});
193+
170194
it('should call onSubmit and onSuccess when invite is successful', async () => {
171195
render(<ContractorOnboardingFlow {...defaultProps} />, {
172196
wrapper: TestProviders,

src/flows/ContractorOnboarding/utils.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,12 +156,14 @@ export const shouldIncludeProduct = (
156156
* @constant
157157
*/
158158
export const reviewStepAllowedEmploymentStatus: Employment['status'][] = [
159+
'initiated',
159160
'invited',
160161
'created_awaiting_reserve',
161162
'created_reserve_paid',
162163
];
163164

164165
export const disabledInviteButtonEmploymentStatus: Employment['status'][] = [
166+
'initiated',
165167
'created_awaiting_reserve',
166168
'invited',
167169
];

src/flows/Onboarding/README.md

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -790,26 +790,26 @@ The `creditRiskState` can have the following values:
790790

791791
The `onboardingBag` object returned by the `useOnboarding` hook contains the following properties:
792792

793-
| Property | Type | Description |
794-
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
795-
| `employmentId` | `string \| undefined` | Employment ID passed useful to be used between components |
796-
| `creditRiskStatus` | `'not_started' \| 'ready' \| 'in_progress' \| 'referred' \| 'fail' \| 'deposit_required' \| 'no_deposit_required' \| undefined` | Credit risk status of the company, useful to know what to show in the review step |
797-
| `stepState` | `{ currentStep: { name: string; index: number }; totalSteps: number; values: Record<string, any> } }` | Current step state containing the current step and total number of steps |
798-
| `fields` | `Fields[]` | Array of form fields from the onboarding schema for the current step |
799-
| `isLoading` | `boolean` | Loading state indicating if the onboarding schema is being fetched |
800-
| `isSubmitting` | `boolean` | Loading state indicating if the onboarding mutation is in progress |
801-
| `initialValues` | `Record<string, any>` | Initial form values for the current step |
802-
| `handleValidation` | `(values: FieldValues) => ValidationResult \| null` | Function to validate form values against the onboarding schema |
803-
| `checkFieldUpdates` | `(values: FieldValues) => void` | Function to update the current form field values |
804-
| `parseFormValues` | `(values: FieldValues) => any` | Function to parse form values before submission |
805-
| `onSubmit` | `(values: FieldValues) => Promise<any>` | Function to handle form submission |
806-
| `back` | `() => void` | Function to handle going back to the previous step |
807-
| `next` | `() => void` | Function to handle going to the next step |
808-
| `goTo` | `(step: string) => void` | Function to handle going to a specific step |
809-
| `meta` | `{ fields: Record<string, any> }` | Fields metadata for each step with prettified values |
810-
| `refetchEmployment` | `() => void` | Function to refetch the employment data |
811-
| `employment` | `Employment \| undefined` | Employment data object |
812-
| `isEmploymentReadOnly` | `boolean` | Indicates that the employment cannot be edited (happens when employment.status is `invited`, `created_awaiting_reserve`, or `created_reserve_paid`) |
793+
| Property | Type | Description |
794+
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
795+
| `employmentId` | `string \| undefined` | Employment ID passed useful to be used between components |
796+
| `creditRiskStatus` | `'not_started' \| 'ready' \| 'in_progress' \| 'referred' \| 'fail' \| 'deposit_required' \| 'no_deposit_required' \| undefined` | Credit risk status of the company, useful to know what to show in the review step |
797+
| `stepState` | `{ currentStep: { name: string; index: number }; totalSteps: number; values: Record<string, any> } }` | Current step state containing the current step and total number of steps |
798+
| `fields` | `Fields[]` | Array of form fields from the onboarding schema for the current step |
799+
| `isLoading` | `boolean` | Loading state indicating if the onboarding schema is being fetched |
800+
| `isSubmitting` | `boolean` | Loading state indicating if the onboarding mutation is in progress |
801+
| `initialValues` | `Record<string, any>` | Initial form values for the current step |
802+
| `handleValidation` | `(values: FieldValues) => ValidationResult \| null` | Function to validate form values against the onboarding schema |
803+
| `checkFieldUpdates` | `(values: FieldValues) => void` | Function to update the current form field values |
804+
| `parseFormValues` | `(values: FieldValues) => any` | Function to parse form values before submission |
805+
| `onSubmit` | `(values: FieldValues) => Promise<any>` | Function to handle form submission |
806+
| `back` | `() => void` | Function to handle going back to the previous step |
807+
| `next` | `() => void` | Function to handle going to the next step |
808+
| `goTo` | `(step: string) => void` | Function to handle going to a specific step |
809+
| `meta` | `{ fields: Record<string, any> }` | Fields metadata for each step with prettified values |
810+
| `refetchEmployment` | `() => void` | Function to refetch the employment data |
811+
| `employment` | `Employment \| undefined` | Employment data object |
812+
| `isEmploymentReadOnly` | `boolean` | Indicates that the employment cannot be edited (happens when employment.status is `invited`, `created_awaiting_reserve`, `initiated` and `created_reserve_paid`) |
813813

814814
### Credit Risk Status Values
815815

src/flows/Onboarding/components/OnboardingInvite.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,14 +131,16 @@ export function OnboardingInvite({
131131
throw new Error(`Button component not found`);
132132
}
133133

134+
const disabled =
135+
!onboardingBag.canInvite ||
136+
employmentInviteMutation.isPending ||
137+
useCreateReserveInvoiceMutation.isPending ||
138+
props.disabled;
139+
134140
return (
135141
<CustomButton
136142
{...props}
137-
disabled={
138-
employmentInviteMutation.isPending ||
139-
useCreateReserveInvoiceMutation.isPending ||
140-
props.disabled
141-
}
143+
disabled={disabled}
142144
onClick={(evt) => {
143145
handleSubmit();
144146
props.onClick?.(evt);

src/flows/Onboarding/tests/OnboardingFlow.test.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1089,7 +1089,12 @@ describe('OnboardingFlow', () => {
10891089
});
10901090
});
10911091

1092-
it.each(['invited', 'created_awaiting_reserve', 'created_reserve_paid'])(
1092+
it.each([
1093+
'invited',
1094+
'created_awaiting_reserve',
1095+
'created_reserve_paid',
1096+
'initiated',
1097+
])(
10931098
'should automatically navigate to review step when employment status is %s and display employment data',
10941099
async (status) => {
10951100
const employmentId = generateUniqueEmploymentId();

0 commit comments

Comments
 (0)