diff --git a/example/src/Onboarding.tsx b/example/src/Onboarding.tsx
index 1104c2237..c944a8819 100644
--- a/example/src/Onboarding.tsx
+++ b/example/src/Onboarding.tsx
@@ -90,6 +90,7 @@ const MultiStepForm = ({ components, onboardingBag }: MultiStepFormProps) => {
BackButton,
SelectCountryStep,
EngagementAgreementDetailsStep,
+ PreviewEmploymentAgreementStep,
} = components;
const [errors, setErrors] = useState<{
apiError: string;
@@ -268,6 +269,27 @@ const MultiStepForm = ({ components, onboardingBag }: MultiStepFormProps) => {
);
}
+ case 'employment_agreement_preview': {
+ return (
+ <>
+
+
+ setErrors({ apiError: '', fieldErrors: [] })}
+ >
+ Previous Step
+
+ setErrors({ apiError: '', fieldErrors: [] })}
+ >
+ Continue
+
+
+ >
+ );
+ }
case 'review':
return (
(
+ options?: Options,
+) =>
+ (options?.client ?? client).get<
+ GetV1EmployeeBankAccountResponses,
+ GetV1EmployeeBankAccountErrors,
+ ThrowOnError
+ >({
+ security: [{ scheme: 'bearer', type: 'http' }],
+ url: '/v1/employee/bank-account',
+ ...options,
+ });
+
+/**
+ * Update employee bank account
+ *
+ * Upserts the authenticated employee's bank account details.
+ *
+ * This endpoint requires and returns country-specific data. The exact fields vary depending on which
+ * country the authenticated employee's employment is in. Query the
+ * [Show form schema](#tag/Countries/operation/get_show_form_country) endpoint with `bank_account_details`
+ * as the form name to discover the schema for a given country.
+ *
+ *
+ *
+ * ## Scopes
+ *
+ * | Category | Read only Scope | Write only Scope (read access implicit) |
+ * |---|---|---|
+ * | Manage employments (`employments`) | - | Manage bank accounts (`bank_account:write`) |
+ *
+ */
+export const putV1EmployeeBankAccount = (
+ options?: Options,
+) =>
+ (options?.client ?? client).put<
+ PutV1EmployeeBankAccountResponses,
+ PutV1EmployeeBankAccountErrors,
+ ThrowOnError
+ >({
+ security: [{ scheme: 'bearer', type: 'http' }],
+ url: '/v1/employee/bank-account',
+ ...options,
+ headers: {
+ 'Content-Type': 'application/json',
+ ...options?.headers,
+ },
+ });
+
/**
* Get Help Center Article
*
@@ -1802,7 +1897,7 @@ export const getV1ContractorsEmploymentsEmploymentIdContractorSubscriptions = <
*
* | Category | Read only Scope | Write only Scope (read access implicit) |
* |---|---|---|
- * | Manage payroll runs (`payroll`) | View payslips (`payslip:read`) | - |
+ * | Manage employment documents (`employment_documents`) | View payslips (`payslip:read`) | - |
*
*/
export const getV1EmployeePayslips = (
@@ -1818,6 +1913,38 @@ export const getV1EmployeePayslips = (
...options,
});
+/**
+ * List contractor of record (COR) termination requests
+ *
+ * Lists Contractor of Record termination requests for your company,
+ * optionally filtered by employment and status.
+ *
+ *
+ * ## Scopes
+ *
+ * | Category | Read only Scope | Write only Scope (read access implicit) |
+ * |---|---|---|
+ * | Manage employments (`employments`) | View employments (`employment:read`) | Manage employments (`employment:write`) |
+ *
+ */
+export const getV1ContractorsCorTerminationRequests = <
+ ThrowOnError extends boolean = false,
+>(
+ options?: Options,
+) =>
+ (options?.client ?? client).get<
+ GetV1ContractorsCorTerminationRequestsResponses,
+ GetV1ContractorsCorTerminationRequestsErrors,
+ ThrowOnError
+ >({
+ security: [
+ { scheme: 'bearer', type: 'http' },
+ { scheme: 'bearer', type: 'http' },
+ ],
+ url: '/v1/contractors/cor-termination-requests',
+ ...options,
+ });
+
/**
* List Webhook Events
*
@@ -2707,6 +2834,57 @@ export const postV1MagicLink = (
},
});
+/**
+ * Get basic information
+ *
+ * Returns the employment's basic information.
+ *
+ * This endpoint requires and returns country-specific data. The exact required and returned fields will
+ * vary depending on which country the employment is in. To see the list of parameters for each country,
+ * see the **Show form schema** endpoint under the [Countries](#tag/Countries) category.
+ *
+ * Please note that the compliance requirements for each country are subject to change according to local
+ * laws. Given its continual updates, using Remote's [json-schema-form](https://developer.remote.com/docs/how-json-schemas-work) should be considered in order to avoid
+ * compliance issues and to have the latest version of a country requirements.
+ *
+ * If you are using this endpoint to build an integration, make sure you are dynamically collecting or
+ * displaying the latest parameters for each country by querying the _"Show form schema"_ endpoint.
+ *
+ * For more information on JSON Schemas, see the **How JSON Schemas work** documentation.
+ *
+ * To learn how you can dynamically generate forms to display in your UI, see the documentation for
+ * the [json-schema-form](https://developer.remote.com/docs/how-json-schemas-work) tool.
+ *
+ *
+ *
+ * ## Scopes
+ *
+ * | Category | Read only Scope | Write only Scope (read access implicit) |
+ * |---|---|---|
+ * | Manage employments (`employments`) | View employments (`employment:read`) | Manage employments (`employment:write`) |
+ *
+ */
+export const getV2EmploymentsEmploymentIdBasicInformation = <
+ ThrowOnError extends boolean = false,
+>(
+ options: Options<
+ GetV2EmploymentsEmploymentIdBasicInformationData,
+ ThrowOnError
+ >,
+) =>
+ (options.client ?? client).get<
+ GetV2EmploymentsEmploymentIdBasicInformationResponses,
+ GetV2EmploymentsEmploymentIdBasicInformationErrors,
+ ThrowOnError
+ >({
+ security: [
+ { scheme: 'bearer', type: 'http' },
+ { scheme: 'bearer', type: 'http' },
+ ],
+ url: '/v2/employments/{employment_id}/basic_information',
+ ...options,
+ });
+
/**
* Update basic information
*
@@ -3921,6 +4099,44 @@ export const postV1ContractAmendments = (
},
});
+/**
+ * Download the Employment Agreement for an employment
+ *
+ * Downloads a PDF of the auto-generated Employment Agreement for an employment.
+ *
+ * The document is rendered as a draft (no signatures) and is not persisted. EA preview is only
+ * available for countries that have a published Employment Agreement automation template — see the
+ * `employment_agreement_preview_available` flag on the [Countries](#tag/Countries) endpoint.
+ *
+ *
+ * ## Scopes
+ *
+ * | Category | Read only Scope | Write only Scope (read access implicit) |
+ * |---|---|---|
+ * | Manage employment documents (`employment_documents`) | View documents (`document:read`) | Manage documents (`document:write`) |
+ *
+ */
+export const getV1EmploymentsEmploymentIdEmploymentAgreementDownload = <
+ ThrowOnError extends boolean = false,
+>(
+ options: Options<
+ GetV1EmploymentsEmploymentIdEmploymentAgreementDownloadData,
+ ThrowOnError
+ >,
+) =>
+ (options.client ?? client).get<
+ GetV1EmploymentsEmploymentIdEmploymentAgreementDownloadResponses,
+ GetV1EmploymentsEmploymentIdEmploymentAgreementDownloadErrors,
+ ThrowOnError
+ >({
+ security: [
+ { scheme: 'bearer', type: 'http' },
+ { scheme: 'bearer', type: 'http' },
+ ],
+ url: '/v1/employments/{employment_id}/employment-agreement/download',
+ ...options,
+ });
+
/**
* Show Company Payroll Runs
*
@@ -4250,9 +4466,11 @@ export const postV1EmployeeTimeoffIdCancel = <
* - pricing_plan_details
* - company_basic_information
* - global_payroll_administrative_details
+ * - global_payroll_bank_account_details
* - global_payroll_basic_information
* - global_payroll_contract_details
* - global_payroll_federal_taxes
+ * - global_payroll_state_taxes
* - global_payroll_personal_details
* - benefit_renewal_request
* - hris_personal_details
@@ -4935,7 +5153,7 @@ export const postV1TimesheetsTimesheetIdApprove = <
*
* | Category | Read only Scope | Write only Scope (read access implicit) |
* |---|---|---|
- * | Manage payroll runs (`payroll`) | View payslips (`payslip:read`) | - |
+ * | Manage employment documents (`employment_documents`) | View payslips (`payslip:read`) | - |
*
*/
export const getV1PayslipsId = (
@@ -5072,6 +5290,36 @@ export const postV1CompanyDepartments = (
},
});
+/**
+ * List Offboardings for Employment
+ *
+ * Lists Offboarding requests for a specific employment.
+ *
+ * ## Scopes
+ *
+ * | Category | Read only Scope | Write only Scope (read access implicit) |
+ * |---|---|---|
+ * | Manage employments (`employments`) | View offboarding requests (`offboarding:read`) | Manage offboarding (`offboarding:write`) |
+ *
+ */
+export const getV1OffboardingsEmploymentsEmploymentId = <
+ ThrowOnError extends boolean = false,
+>(
+ options: Options,
+) =>
+ (options.client ?? client).get<
+ GetV1OffboardingsEmploymentsEmploymentIdResponses,
+ GetV1OffboardingsEmploymentsEmploymentIdErrors,
+ ThrowOnError
+ >({
+ security: [
+ { scheme: 'bearer', type: 'http' },
+ { scheme: 'bearer', type: 'http' },
+ ],
+ url: '/v1/offboardings/employments/{employment_id}',
+ ...options,
+ });
+
/**
* Decline a time off cancellation request
*
@@ -6020,7 +6268,7 @@ export const getV1Countries = (
*
* | Category | Read only Scope | Write only Scope (read access implicit) |
* |---|---|---|
- * | Manage payroll runs (`payroll`) | View payslips (`payslip:read`) | - |
+ * | Manage employment documents (`employment_documents`) | View payslips (`payslip:read`) | - |
*
*/
export const getV1EmployeePayslipFiles = (
@@ -6258,6 +6506,39 @@ export const postV1CostCalculatorEstimationCsv = <
},
});
+/**
+ * Activate Global Payroll for a legal entity
+ *
+ * Enables the Global Payroll product on a legal entity so that GP employees can be created against it.
+ *
+ * Performs three idempotent steps:
+ * * Adds the Global Payroll product to the company.
+ * * Flips `global_payroll_enabled` on the legal entity's settings.
+ * * Ensures a Global Payroll pricing plan exists for the legal entity's country.
+ *
+ * This endpoint is only available in Sandbox, otherwise it will respond with a 404.
+ *
+ */
+export const postV1SandboxCompaniesCompanyIdLegalEntitiesLegalEntityIdActivateGlobalPayroll =
+ (
+ options: Options<
+ PostV1SandboxCompaniesCompanyIdLegalEntitiesLegalEntityIdActivateGlobalPayrollData,
+ ThrowOnError
+ >,
+ ) =>
+ (options.client ?? client).post<
+ PostV1SandboxCompaniesCompanyIdLegalEntitiesLegalEntityIdActivateGlobalPayrollResponses,
+ PostV1SandboxCompaniesCompanyIdLegalEntitiesLegalEntityIdActivateGlobalPayrollErrors,
+ ThrowOnError
+ >({
+ security: [
+ { scheme: 'bearer', type: 'http' },
+ { scheme: 'bearer', type: 'http' },
+ ],
+ url: '/v1/sandbox/companies/{company_id}/legal-entities/{legal_entity_id}/activate-global-payroll',
+ ...options,
+ });
+
/**
* Show employee personal details
*
@@ -6426,7 +6707,7 @@ export const postV1SandboxWebhookCallbacksTrigger = <
*
* | Category | Read only Scope | Write only Scope (read access implicit) |
* |---|---|---|
- * | Manage payroll runs (`payroll`) | View payslips (`payslip:read`) | - |
+ * | Manage employment documents (`employment_documents`) | View payslips (`payslip:read`) | - |
*
*/
export const getV1PayslipsPayslipIdPdf = (
@@ -8168,7 +8449,7 @@ export const getV1ProbationExtensionsId = <
*
* | Category | Read only Scope | Write only Scope (read access implicit) |
* |---|---|---|
- * | Manage payroll runs (`payroll`) | View payslips (`payslip:read`) | - |
+ * | Manage employment documents (`employment_documents`) | View payslips (`payslip:read`) | - |
*
*/
export const getV1Payslips = (
@@ -9050,6 +9331,47 @@ export const postV1ContractorInvoiceSchedules = <
},
});
+/**
+ * Submit employee state taxes
+ *
+ * Submits the authenticated employee's US state tax withholding answers for a
+ * single jurisdiction (e.g. `NY`).
+ *
+ * Available for US Global Payroll employees once they reach the post-enrollment
+ * state, at which point the per-jurisdiction state tax task exists.
+ *
+ * This endpoint requires country/jurisdiction-specific data. Query the
+ * [Show form schema](#tag/Countries/operation/get_show_form_country) endpoint with `global_payroll_state_taxes`
+ * as the form name to discover the schema for a given country.
+ *
+ *
+ *
+ * ## Scopes
+ *
+ * | Category | Read only Scope | Write only Scope (read access implicit) |
+ * |---|---|---|
+ * | Manage employments (`employments`) | - | Manage personal details (`personal_detail:write`) |
+ *
+ */
+export const putV1EmployeeStateTaxesJurisdiction = <
+ ThrowOnError extends boolean = false,
+>(
+ options: Options,
+) =>
+ (options.client ?? client).put<
+ PutV1EmployeeStateTaxesJurisdictionResponses,
+ PutV1EmployeeStateTaxesJurisdictionErrors,
+ ThrowOnError
+ >({
+ security: [{ scheme: 'bearer', type: 'http' }],
+ url: '/v1/employee/state-taxes/{jurisdiction}',
+ ...options,
+ headers: {
+ 'Content-Type': 'application/json',
+ ...options.headers,
+ },
+ });
+
/**
* Get engagement agreement details
*
@@ -9163,6 +9485,44 @@ export const getV1BillingDocumentsBillingDocumentIdBreakdown = <
...options,
});
+/**
+ * Preview the Employment Agreement for an employment
+ *
+ * Returns a base64-encoded PDF preview of the auto-generated Employment Agreement for an employment.
+ *
+ * The document is rendered as a draft (no signatures) and is not persisted. EA preview is only
+ * available for countries that have a published Employment Agreement automation template — see the
+ * `employment_agreement_preview_available` flag on the [Countries](#tag/Countries) endpoint.
+ *
+ *
+ * ## Scopes
+ *
+ * | Category | Read only Scope | Write only Scope (read access implicit) |
+ * |---|---|---|
+ * | Manage employment documents (`employment_documents`) | View documents (`document:read`) | Manage documents (`document:write`) |
+ *
+ */
+export const getV1EmploymentsEmploymentIdEmploymentAgreementPreview = <
+ ThrowOnError extends boolean = false,
+>(
+ options: Options<
+ GetV1EmploymentsEmploymentIdEmploymentAgreementPreviewData,
+ ThrowOnError
+ >,
+) =>
+ (options.client ?? client).get<
+ GetV1EmploymentsEmploymentIdEmploymentAgreementPreviewResponses,
+ GetV1EmploymentsEmploymentIdEmploymentAgreementPreviewErrors,
+ ThrowOnError
+ >({
+ security: [
+ { scheme: 'bearer', type: 'http' },
+ { scheme: 'bearer', type: 'http' },
+ ],
+ url: '/v1/employments/{employment_id}/employment-agreement/preview',
+ ...options,
+ });
+
/**
* Indexes all the documents for the employee
*
diff --git a/src/client/types.gen.ts b/src/client/types.gen.ts
index d72313340..2edfbd6ba 100644
--- a/src/client/types.gen.ts
+++ b/src/client/types.gen.ts
@@ -674,6 +674,48 @@ export type CompanyComplianceProfile = {
| 'unresponsive';
};
+/**
+ * CorTerminationRequest
+ */
+export type CorTerminationRequest = {
+ /**
+ * Timestamp of when the termination was cancelled. Null if not cancelled.
+ */
+ cancelled_at: string | null;
+ /**
+ * The date on which the contractor employment will be deactivated.
+ */
+ employment_deactivation_date: string | null;
+ /**
+ * UuidSlug
+ *
+ * Identifier of the employment being terminated.
+ */
+ employment_id: string;
+ /**
+ * Timestamp of when the termination was executed. Null if not yet executed.
+ */
+ executed_at: string | null;
+ /**
+ * UuidSlug
+ *
+ * Unique identifier of the termination request.
+ */
+ id: string;
+ /**
+ * Timestamp of when the termination request was initiated.
+ */
+ initiated_at: string | null;
+ /**
+ * Current status of the termination request.
+ */
+ status: 'initiated' | 'executed' | 'cancelled';
+ /**
+ * The date when the termination was initiated.
+ */
+ termination_date: string | null;
+};
+
/**
* ResignationOrTerminationOffboarding
*/
@@ -2354,6 +2396,10 @@ export type Country = {
* Administrative subdivisions of the country (e.g., states, provinces, districts). Null if the country has no subdivisions relevant to Remote's services.
*/
country_subdivisions?: Array | null;
+ /**
+ * Whether an Employment Agreement preview is available for this country.
+ */
+ employment_agreement_preview_available?: boolean;
/**
* Whether EOR (Employer of Record) onboarding is available in this country.
*/
@@ -3452,9 +3498,13 @@ export type CostCalculatorCountryLevelRegion = {
/**
* CreateWebhookCallbackParams
*
- * Webhook callback creation params
+ * Webhook callback creation params. Provide either `subscribed_events` or `subscribe_to_all_events: true` (they are mutually exclusive).
*/
export type CreateWebhookCallbackParams = {
+ /**
+ * When true, subscribe this callback to all current and future event types. Cannot be combined with `subscribed_events`.
+ */
+ subscribe_to_all_events?: boolean;
subscribed_events?: Array<
| 'background_check.status.updated'
| 'benefit_renewal_request.created'
@@ -5803,8 +5853,8 @@ export type ResourceErrorResponse = {
| 'parameter_value_unknown'
| 'request_body_empty'
| 'request_internal_server_error'
- | 'parameter_required_missing'
| 'parameter_one_of_required_missing'
+ | 'parameter_required_missing'
| 'parameter_too_many'
| 'parameter_unknown'
| 'parameter_map_empty'
@@ -6782,6 +6832,10 @@ export type NullableCountry = {
* Administrative subdivisions of the country (e.g., states, provinces, districts). Null if the country has no subdivisions relevant to Remote's services.
*/
country_subdivisions?: Array | null;
+ /**
+ * Whether an Employment Agreement preview is available for this country.
+ */
+ employment_agreement_preview_available?: boolean;
/**
* Whether EOR (Employer of Record) onboarding is available in this country.
*/
@@ -7554,7 +7608,7 @@ export type ListCompanyPricingPlansResponse = {
/**
* UuidSlug
*
- * Unique identifier of the termination request.
+ * Identifier of the employment being terminated.
*/
export type UuidSlug = string;
@@ -7717,6 +7771,20 @@ export type Timesheet = {
weekend_hours: HoursAndMinutes;
};
+/**
+ * EmploymentAgreementPreviewResponse
+ *
+ * Return a base64 encoded Employment Agreement preview document
+ */
+export type EmploymentAgreementPreviewResponse = {
+ data: {
+ employment_agreement: {
+ content: Blob | File;
+ name: string;
+ };
+ };
+};
+
/**
* Benefit
*
@@ -9052,6 +9120,10 @@ export type WebhookCallback = {
*
*/
signing_key?: string;
+ /**
+ * When true, this callback is subscribed to all current and future event types. `subscribed_events` then lists every currently supported event.
+ */
+ subscribe_to_all_events?: boolean;
subscribed_events?: Array<
| 'background_check.status.updated'
| 'benefit_renewal_request.created'
@@ -9382,6 +9454,29 @@ export type UnauthorizedResponse = {
message: string;
};
+/**
+ * IndexCorTerminationRequestsResponse
+ *
+ * Response schema listing many termination_requests
+ */
+export type IndexCorTerminationRequestsResponse = {
+ data?: {
+ /**
+ * The current page among all of the total_pages
+ */
+ current_page?: number;
+ termination_requests?: Array;
+ /**
+ * The total number of records in the result
+ */
+ total_count?: number;
+ /**
+ * The total number of pages the user can go through
+ */
+ total_pages?: number;
+ };
+};
+
/**
* PricingPlanDetails
*
@@ -10785,10 +10880,14 @@ export type CreateContractEligibilityParams = {
/**
* UpdateWebhookCallbackParams
*
- * Webhook callback update params
+ * Webhook callback update params. Provide either `subscribed_events` or `subscribe_to_all_events` (they are mutually exclusive). Omitting `subscribe_to_all_events` leaves the current subscription mode unchanged, so resending an event list does not disable all-events delivery. Setting `subscribe_to_all_events: false` requires a non-empty `subscribed_events`.
*/
export type UpdateWebhookCallbackParams = {
- subscribed_events: Array<
+ /**
+ * When true, subscribe this callback to all current and future event types. Cannot be combined with `subscribed_events`.
+ */
+ subscribe_to_all_events?: boolean;
+ subscribed_events?: Array<
| 'background_check.status.updated'
| 'benefit_renewal_request.created'
| 'billing_document.issued'
@@ -11238,6 +11337,24 @@ export type CompanyNotEligibleForCreationErrorResponse = {
resource_type?: string;
};
+/**
+ * EmploymentStateTaxesParams
+ *
+ * State taxes schema compatible params, submitted one jurisdiction at a time.
+ *
+ */
+export type EmploymentStateTaxesParams = {
+ /**
+ * State taxes params for the jurisdiction in the path. As its properties vary depending
+ * on the country and jurisdiction, you must query the
+ * [Show form schema](#tag/Countries/operation/get_show_form_country) endpoint passing the country code
+ * and `global_payroll_state_taxes` as path parameters.
+ */
+ state_taxes: {
+ [key: string]: unknown;
+ };
+};
+
/**
* MinimalContractAmendment
*
@@ -11910,6 +12027,13 @@ export type EmploymentDetailsOnlyResponse = {
contract_details?: {
[key: string]: unknown;
};
+ /**
+ * Origin of the employment contract. Returned by the basic information endpoint.
+ */
+ contract_origin?:
+ | 'remote_contract'
+ | 'custom_remote_contract'
+ | 'provided_by_customer';
/**
* Emergency contact information. Its properties may vary depending on the country. Null if the employee has not submitted their emergency contact yet.
*/
@@ -12123,38 +12247,7 @@ export type PayDifference = {
* CorTerminationRequestResponse
*/
export type CorTerminationRequestResponse = {
- data: {
- /**
- * Timestamp of when the termination was cancelled. Null if not cancelled.
- */
- cancelled_at: string | null;
- /**
- * The date on which the contractor employment will be deactivated.
- */
- employment_deactivation_date: string | null;
- /**
- * Timestamp of when the termination was executed. Null if not yet executed.
- */
- executed_at: string | null;
- /**
- * UuidSlug
- *
- * Unique identifier of the termination request.
- */
- id: string;
- /**
- * Timestamp of when the termination request was initiated.
- */
- initiated_at: string | null;
- /**
- * Current status of the termination request.
- */
- status: 'initiated' | 'executed' | 'cancelled';
- /**
- * The date when the termination was initiated.
- */
- termination_date: string | null;
- };
+ data: CorTerminationRequest;
};
/**
@@ -13300,6 +13393,109 @@ export type GetV1CompaniesCompanyIdEmploymentsEmploymentIdOnboardingReservesStat
export type GetV1CompaniesCompanyIdEmploymentsEmploymentIdOnboardingReservesStatusResponse =
GetV1CompaniesCompanyIdEmploymentsEmploymentIdOnboardingReservesStatusResponses[keyof GetV1CompaniesCompanyIdEmploymentsEmploymentIdOnboardingReservesStatusResponses];
+export type GetV1EmployeeBankAccountData = {
+ body?: never;
+ path?: never;
+ query?: {
+ /**
+ * Version of the bank_account_details form schema
+ */
+ bank_account_details_json_schema_version?: number | 'latest';
+ };
+ url: '/v1/employee/bank-account';
+};
+
+export type GetV1EmployeeBankAccountErrors = {
+ /**
+ * Bad Request
+ */
+ 400: BadRequestResponse;
+ /**
+ * Unauthorized
+ */
+ 401: UnauthorizedResponse;
+ /**
+ * Forbidden
+ */
+ 403: ForbiddenResponse;
+ /**
+ * Not Found
+ */
+ 404: NotFoundResponse;
+ /**
+ * Unprocessable Entity
+ */
+ 429: TooManyRequestsResponse;
+};
+
+export type GetV1EmployeeBankAccountError =
+ GetV1EmployeeBankAccountErrors[keyof GetV1EmployeeBankAccountErrors];
+
+export type GetV1EmployeeBankAccountResponses = {
+ /**
+ * Success
+ */
+ 200: EmploymentDetailsOnlyResponse;
+};
+
+export type GetV1EmployeeBankAccountResponse =
+ GetV1EmployeeBankAccountResponses[keyof GetV1EmployeeBankAccountResponses];
+
+export type PutV1EmployeeBankAccountData = {
+ /**
+ * Employee bank account details params
+ */
+ body?: EmploymentBankAccountDetailsParams;
+ path?: never;
+ query?: {
+ /**
+ * Version of the bank_account_details form schema
+ */
+ bank_account_details_json_schema_version?: number | 'latest';
+ };
+ url: '/v1/employee/bank-account';
+};
+
+export type PutV1EmployeeBankAccountErrors = {
+ /**
+ * Bad Request
+ */
+ 400: BadRequestResponse;
+ /**
+ * Unauthorized
+ */
+ 401: UnauthorizedResponse;
+ /**
+ * Forbidden
+ */
+ 403: ForbiddenResponse;
+ /**
+ * Not Found
+ */
+ 404: NotFoundResponse;
+ /**
+ * Unprocessable Entity
+ */
+ 422: UnprocessableEntityResponse;
+ /**
+ * Unprocessable Entity
+ */
+ 429: TooManyRequestsResponse;
+};
+
+export type PutV1EmployeeBankAccountError =
+ PutV1EmployeeBankAccountErrors[keyof PutV1EmployeeBankAccountErrors];
+
+export type PutV1EmployeeBankAccountResponses = {
+ /**
+ * Success
+ */
+ 200: EmploymentDetailsOnlyResponse;
+};
+
+export type PutV1EmployeeBankAccountResponse =
+ PutV1EmployeeBankAccountResponses[keyof PutV1EmployeeBankAccountResponses];
+
export type GetV1HelpCenterArticlesIdData = {
body?: never;
path: {
@@ -13995,6 +14191,54 @@ export type GetV1EmployeePayslipsResponses = {
export type GetV1EmployeePayslipsResponse =
GetV1EmployeePayslipsResponses[keyof GetV1EmployeePayslipsResponses];
+export type GetV1ContractorsCorTerminationRequestsData = {
+ body?: never;
+ path?: never;
+ query?: {
+ /**
+ * Filter termination requests by employment ID.
+ */
+ employment_id?: UuidSlug;
+ /**
+ * Filter termination requests by status.
+ */
+ status?: 'initiated' | 'executed' | 'cancelled';
+ /**
+ * Starts fetching records after the given page
+ */
+ page?: number;
+ /**
+ * Number of items per page
+ */
+ page_size?: number;
+ };
+ url: '/v1/contractors/cor-termination-requests';
+};
+
+export type GetV1ContractorsCorTerminationRequestsErrors = {
+ /**
+ * Forbidden
+ */
+ 403: ForbiddenResponse;
+ /**
+ * Not Found
+ */
+ 404: NotFoundResponse;
+};
+
+export type GetV1ContractorsCorTerminationRequestsError =
+ GetV1ContractorsCorTerminationRequestsErrors[keyof GetV1ContractorsCorTerminationRequestsErrors];
+
+export type GetV1ContractorsCorTerminationRequestsResponses = {
+ /**
+ * Success
+ */
+ 200: IndexCorTerminationRequestsResponse;
+};
+
+export type GetV1ContractorsCorTerminationRequestsResponse =
+ GetV1ContractorsCorTerminationRequestsResponses[keyof GetV1ContractorsCorTerminationRequestsResponses];
+
export type GetV1WebhookEventsData = {
body?: never;
path?: never;
@@ -15430,6 +15674,59 @@ export type PostV1MagicLinkResponses = {
export type PostV1MagicLinkResponse =
PostV1MagicLinkResponses[keyof PostV1MagicLinkResponses];
+export type GetV2EmploymentsEmploymentIdBasicInformationData = {
+ body?: never;
+ path: {
+ /**
+ * Employment ID
+ */
+ employment_id: string;
+ };
+ query?: {
+ /**
+ * Version of the employment_basic_information form schema
+ */
+ employment_basic_information_json_schema_version?: number | 'latest';
+ };
+ url: '/v2/employments/{employment_id}/basic_information';
+};
+
+export type GetV2EmploymentsEmploymentIdBasicInformationErrors = {
+ /**
+ * Bad Request
+ */
+ 400: BadRequestResponse;
+ /**
+ * Forbidden
+ */
+ 403: ForbiddenResponse;
+ /**
+ * Not Found
+ */
+ 404: NotFoundResponse;
+ /**
+ * Unprocessable Entity
+ */
+ 422: UnprocessableEntityResponse;
+ /**
+ * Unprocessable Entity
+ */
+ 429: TooManyRequestsResponse;
+};
+
+export type GetV2EmploymentsEmploymentIdBasicInformationError =
+ GetV2EmploymentsEmploymentIdBasicInformationErrors[keyof GetV2EmploymentsEmploymentIdBasicInformationErrors];
+
+export type GetV2EmploymentsEmploymentIdBasicInformationResponses = {
+ /**
+ * Success
+ */
+ 200: EmploymentDetailsOnlyResponse;
+};
+
+export type GetV2EmploymentsEmploymentIdBasicInformationResponse =
+ GetV2EmploymentsEmploymentIdBasicInformationResponses[keyof GetV2EmploymentsEmploymentIdBasicInformationResponses];
+
export type PutV2EmploymentsEmploymentIdBasicInformationData = {
/**
* Employment basic information params
@@ -17053,6 +17350,46 @@ export type PostV1ContractAmendmentsResponses = {
export type PostV1ContractAmendmentsResponse =
PostV1ContractAmendmentsResponses[keyof PostV1ContractAmendmentsResponses];
+export type GetV1EmploymentsEmploymentIdEmploymentAgreementDownloadData = {
+ body?: never;
+ path: {
+ /**
+ * Employment ID
+ */
+ employment_id: string;
+ };
+ query?: never;
+ url: '/v1/employments/{employment_id}/employment-agreement/download';
+};
+
+export type GetV1EmploymentsEmploymentIdEmploymentAgreementDownloadErrors = {
+ /**
+ * Unauthorized
+ */
+ 401: UnauthorizedResponse;
+ /**
+ * Not Found
+ */
+ 404: NotFoundResponse;
+ /**
+ * Unprocessable Entity
+ */
+ 422: UnprocessableEntityResponse;
+};
+
+export type GetV1EmploymentsEmploymentIdEmploymentAgreementDownloadError =
+ GetV1EmploymentsEmploymentIdEmploymentAgreementDownloadErrors[keyof GetV1EmploymentsEmploymentIdEmploymentAgreementDownloadErrors];
+
+export type GetV1EmploymentsEmploymentIdEmploymentAgreementDownloadResponses = {
+ /**
+ * Success
+ */
+ 200: GenericFile;
+};
+
+export type GetV1EmploymentsEmploymentIdEmploymentAgreementDownloadResponse =
+ GetV1EmploymentsEmploymentIdEmploymentAgreementDownloadResponses[keyof GetV1EmploymentsEmploymentIdEmploymentAgreementDownloadResponses];
+
export type GetV1PayrollRunsPayrollRunIdData = {
body?: never;
path: {
@@ -17513,9 +17850,13 @@ export type GetV1CountriesCountryCodeFormData = {
};
query?: {
/**
- * Required for `contract_amendment` form
+ * Required for `contract_amendment` and `global_payroll_state_taxes` forms
*/
employment_id?: string;
+ /**
+ * Two-letter US state code. Required for `global_payroll_state_taxes` (e.g. `NY`).
+ */
+ jurisdiction?: string;
/**
* FOR TESTING PURPOSES ONLY: Include scheduled benefit groups.
*/
@@ -18736,6 +19077,63 @@ export type PostV1CompanyDepartmentsResponses = {
export type PostV1CompanyDepartmentsResponse =
PostV1CompanyDepartmentsResponses[keyof PostV1CompanyDepartmentsResponses];
+export type GetV1OffboardingsEmploymentsEmploymentIdData = {
+ body?: never;
+ path: {
+ /**
+ * Employment ID
+ */
+ employment_id: string;
+ };
+ query?: {
+ /**
+ * Starts fetching records after the given page
+ */
+ page?: number;
+ /**
+ * Change the amount of records returned per page, defaults to 20, limited to 100
+ */
+ page_size?: number;
+ };
+ url: '/v1/offboardings/employments/{employment_id}';
+};
+
+export type GetV1OffboardingsEmploymentsEmploymentIdErrors = {
+ /**
+ * Bad Request
+ */
+ 400: BadRequestResponse;
+ /**
+ * Unauthorized
+ */
+ 401: UnauthorizedResponse;
+ /**
+ * Not Found
+ */
+ 404: NotFoundResponse;
+ /**
+ * Unprocessable Entity
+ */
+ 422: UnprocessableEntityResponse;
+ /**
+ * Too many requests
+ */
+ 429: TooManyRequestsResponse;
+};
+
+export type GetV1OffboardingsEmploymentsEmploymentIdError =
+ GetV1OffboardingsEmploymentsEmploymentIdErrors[keyof GetV1OffboardingsEmploymentsEmploymentIdErrors];
+
+export type GetV1OffboardingsEmploymentsEmploymentIdResponses = {
+ /**
+ * Success
+ */
+ 200: ListOffboardingResponse;
+};
+
+export type GetV1OffboardingsEmploymentsEmploymentIdResponse =
+ GetV1OffboardingsEmploymentsEmploymentIdResponses[keyof GetV1OffboardingsEmploymentsEmploymentIdResponses];
+
export type PostV1TimeoffTimeoffIdCancelRequestDeclineData = {
/**
* Timeoff
@@ -20485,6 +20883,61 @@ export type PostV1CostCalculatorEstimationCsvResponses = {
export type PostV1CostCalculatorEstimationCsvResponse =
PostV1CostCalculatorEstimationCsvResponses[keyof PostV1CostCalculatorEstimationCsvResponses];
+export type PostV1SandboxCompaniesCompanyIdLegalEntitiesLegalEntityIdActivateGlobalPayrollData =
+ {
+ body?: never;
+ path: {
+ /**
+ * Company ID
+ */
+ company_id: string;
+ /**
+ * Legal Entity ID to activate Global Payroll on
+ */
+ legal_entity_id: string;
+ };
+ query?: never;
+ url: '/v1/sandbox/companies/{company_id}/legal-entities/{legal_entity_id}/activate-global-payroll';
+ };
+
+export type PostV1SandboxCompaniesCompanyIdLegalEntitiesLegalEntityIdActivateGlobalPayrollErrors =
+ {
+ /**
+ * Bad Request
+ */
+ 400: BadRequestResponse;
+ /**
+ * Unauthorized
+ */
+ 401: UnauthorizedResponse;
+ /**
+ * Not Found
+ */
+ 404: NotFoundResponse;
+ /**
+ * Unprocessable Entity
+ */
+ 422: UnprocessableEntityResponse;
+ /**
+ * Too many requests
+ */
+ 429: TooManyRequestsResponse;
+ };
+
+export type PostV1SandboxCompaniesCompanyIdLegalEntitiesLegalEntityIdActivateGlobalPayrollError =
+ PostV1SandboxCompaniesCompanyIdLegalEntitiesLegalEntityIdActivateGlobalPayrollErrors[keyof PostV1SandboxCompaniesCompanyIdLegalEntitiesLegalEntityIdActivateGlobalPayrollErrors];
+
+export type PostV1SandboxCompaniesCompanyIdLegalEntitiesLegalEntityIdActivateGlobalPayrollResponses =
+ {
+ /**
+ * Success
+ */
+ 200: SuccessResponse;
+ };
+
+export type PostV1SandboxCompaniesCompanyIdLegalEntitiesLegalEntityIdActivateGlobalPayrollResponse =
+ PostV1SandboxCompaniesCompanyIdLegalEntitiesLegalEntityIdActivateGlobalPayrollResponses[keyof PostV1SandboxCompaniesCompanyIdLegalEntitiesLegalEntityIdActivateGlobalPayrollResponses];
+
export type GetV1EmployeePersonalDetailsData = {
body?: never;
path?: never;
@@ -24896,6 +25349,61 @@ export type PostV1ContractorInvoiceSchedulesResponses = {
export type PostV1ContractorInvoiceSchedulesResponse =
PostV1ContractorInvoiceSchedulesResponses[keyof PostV1ContractorInvoiceSchedulesResponses];
+export type PutV1EmployeeStateTaxesJurisdictionData = {
+ /**
+ * Employee state taxes params
+ */
+ body?: EmploymentStateTaxesParams;
+ path: {
+ /**
+ * Two-letter US state/jurisdiction code
+ */
+ jurisdiction: string;
+ };
+ query?: never;
+ url: '/v1/employee/state-taxes/{jurisdiction}';
+};
+
+export type PutV1EmployeeStateTaxesJurisdictionErrors = {
+ /**
+ * Bad Request
+ */
+ 400: BadRequestResponse;
+ /**
+ * Unauthorized
+ */
+ 401: UnauthorizedResponse;
+ /**
+ * Forbidden
+ */
+ 403: ForbiddenResponse;
+ /**
+ * Not Found
+ */
+ 404: NotFoundResponse;
+ /**
+ * Unprocessable Entity
+ */
+ 422: UnprocessableEntityResponse;
+ /**
+ * Unprocessable Entity
+ */
+ 429: TooManyRequestsResponse;
+};
+
+export type PutV1EmployeeStateTaxesJurisdictionError =
+ PutV1EmployeeStateTaxesJurisdictionErrors[keyof PutV1EmployeeStateTaxesJurisdictionErrors];
+
+export type PutV1EmployeeStateTaxesJurisdictionResponses = {
+ /**
+ * Success
+ */
+ 200: SuccessResponse;
+};
+
+export type PutV1EmployeeStateTaxesJurisdictionResponse =
+ PutV1EmployeeStateTaxesJurisdictionResponses[keyof PutV1EmployeeStateTaxesJurisdictionResponses];
+
export type GetV1EmploymentsEmploymentIdEngagementAgreementDetailsData = {
body?: never;
path: {
@@ -25052,6 +25560,46 @@ export type GetV1BillingDocumentsBillingDocumentIdBreakdownResponses = {
export type GetV1BillingDocumentsBillingDocumentIdBreakdownResponse =
GetV1BillingDocumentsBillingDocumentIdBreakdownResponses[keyof GetV1BillingDocumentsBillingDocumentIdBreakdownResponses];
+export type GetV1EmploymentsEmploymentIdEmploymentAgreementPreviewData = {
+ body?: never;
+ path: {
+ /**
+ * Employment ID
+ */
+ employment_id: string;
+ };
+ query?: never;
+ url: '/v1/employments/{employment_id}/employment-agreement/preview';
+};
+
+export type GetV1EmploymentsEmploymentIdEmploymentAgreementPreviewErrors = {
+ /**
+ * Unauthorized
+ */
+ 401: UnauthorizedResponse;
+ /**
+ * Not Found
+ */
+ 404: NotFoundResponse;
+ /**
+ * Unprocessable Entity
+ */
+ 422: UnprocessableEntityResponse;
+};
+
+export type GetV1EmploymentsEmploymentIdEmploymentAgreementPreviewError =
+ GetV1EmploymentsEmploymentIdEmploymentAgreementPreviewErrors[keyof GetV1EmploymentsEmploymentIdEmploymentAgreementPreviewErrors];
+
+export type GetV1EmploymentsEmploymentIdEmploymentAgreementPreviewResponses = {
+ /**
+ * Success
+ */
+ 200: EmploymentAgreementPreviewResponse;
+};
+
+export type GetV1EmploymentsEmploymentIdEmploymentAgreementPreviewResponse =
+ GetV1EmploymentsEmploymentIdEmploymentAgreementPreviewResponses[keyof GetV1EmploymentsEmploymentIdEmploymentAgreementPreviewResponses];
+
export type GetV1EmployeeDocumentsData = {
body?: never;
path?: never;
diff --git a/src/flows/Onboarding/OnboardingFlow.tsx b/src/flows/Onboarding/OnboardingFlow.tsx
index fdcfab949..6c1b28361 100644
--- a/src/flows/Onboarding/OnboardingFlow.tsx
+++ b/src/flows/Onboarding/OnboardingFlow.tsx
@@ -13,6 +13,7 @@ import { ReviewStep } from '@/src/flows/Onboarding/components/ReviewStep';
import { SaveDraftButton } from '@/src/flows/Onboarding/components/SaveDraftButton';
import { EngagementAgreementDetailsStep } from '@/src/flows/Onboarding/components/EngagementAgreementDetailsStep';
import { PreOnboardingRequirements } from '@/src/flows/Onboarding/components/PreOnboardingRequirements';
+import { PreviewEmploymentAgreementStep } from '@/src/flows/Onboarding/components/PreviewEmploymentAgreementStep';
export const OnboardingFlow = ({
employmentId,
@@ -68,6 +69,7 @@ export const OnboardingFlow = ({
SelectCountryStep: SelectCountryStep,
ReviewStep: ReviewStep,
PreOnboardingRequirements: PreOnboardingRequirements,
+ PreviewEmploymentAgreementStep: PreviewEmploymentAgreementStep,
},
})}
diff --git a/src/flows/Onboarding/api.ts b/src/flows/Onboarding/api.ts
index 19db49c8b..d81de3e64 100644
--- a/src/flows/Onboarding/api.ts
+++ b/src/flows/Onboarding/api.ts
@@ -415,6 +415,8 @@ export const useCountriesSchemaField = (
return {
label: country.name,
value: country.code,
+ employment_agreement_preview_available:
+ country.employment_agreement_preview_available,
};
}) || []
);
@@ -440,6 +442,7 @@ export const useCountriesSchemaField = (
return {
isLoading,
selectCountryForm,
+ countries,
};
};
diff --git a/src/flows/Onboarding/components/PreviewEmploymentAgreementStep.tsx b/src/flows/Onboarding/components/PreviewEmploymentAgreementStep.tsx
new file mode 100644
index 000000000..d6cd728bb
--- /dev/null
+++ b/src/flows/Onboarding/components/PreviewEmploymentAgreementStep.tsx
@@ -0,0 +1,14 @@
+import { useOnboardingContext } from '@/src/flows/Onboarding/context';
+import { OnboardingForm } from '@/src/flows/Onboarding/components/OnboardingForm';
+
+export function PreviewEmploymentAgreementStep() {
+ const { onboardingBag } = useOnboardingContext();
+
+ const handleSubmit = async () => {
+ onboardingBag?.next();
+ };
+
+ // this step in theory shouldn't be a form, not sure yet...
+
+ return ;
+}
diff --git a/src/flows/Onboarding/hooks.tsx b/src/flows/Onboarding/hooks.tsx
index e796c908b..06c03ccc1 100644
--- a/src/flows/Onboarding/hooks.tsx
+++ b/src/flows/Onboarding/hooks.tsx
@@ -63,6 +63,7 @@ const stepToFormSchemaMap: Record = {
engagement_agreement_details: null,
contract_details: 'contract_details',
benefits: null,
+ employment_agreement_preview: null,
review: null,
};
@@ -165,12 +166,21 @@ export const useOnboarding = ({
const [internalCountryCode, setInternalCountryCode] = useState(
countryCode || null,
);
+
const [
includeEngagementAgreementDetails,
setIncludeEngagementAgreementDetails,
] = useState(false);
+ const [
+ includeEmploymentAgreementPreview,
+ setIncludeEmploymentAgreementPreview,
+ ] = useState(false);
+
const useDynamicSteps = options?.features?.includes('dynamic_steps') ?? false;
+ const useEAPreview =
+ options?.features?.includes('ea_preview') &&
+ includeEmploymentAgreementPreview;
const { steps, stepsArray } = useMemo(
() =>
@@ -178,8 +188,14 @@ export const useOnboarding = ({
includeSelectCountry: !skipSteps?.includes('select_country'),
includeEngagementAgreementDetails,
useDynamicSteps,
+ useEAPreview,
}),
- [includeEngagementAgreementDetails, skipSteps, useDynamicSteps],
+ [
+ includeEngagementAgreementDetails,
+ skipSteps,
+ useDynamicSteps,
+ useEAPreview,
+ ],
);
const onStepChange = useCallback(
@@ -260,12 +276,14 @@ export const useOnboarding = ({
contract_details: NestedMeta;
benefits: NestedMeta;
engagement_agreement_details: NestedMeta;
+ employment_agreement_preview: NestedMeta;
}>({
select_country: {},
basic_information: {},
contract_details: {},
benefits: {},
engagement_agreement_details: {},
+ employment_agreement_preview: {},
});
const {
@@ -331,13 +349,27 @@ export const useOnboarding = ({
isErrorPreOnboardingRequirements,
]);
- const { selectCountryForm, isLoading: isLoadingCountries } =
- useCountriesSchemaField({
- jsfModify: options?.jsfModify?.select_country,
- queryOptions: {
- enabled: stepState.currentStep.name === 'select_country',
- },
- });
+ const {
+ selectCountryForm,
+ isLoading: isLoadingCountries,
+ countries,
+ } = useCountriesSchemaField({
+ jsfModify: options?.jsfModify?.select_country,
+ queryOptions: {
+ enabled: stepState.currentStep.name === 'select_country',
+ },
+ });
+
+ const isEmploymentAgreementPreviewAvailable = useMemo(() => {
+ return Boolean(
+ countries?.find((country) => country.value === internalCountryCode)
+ ?.employment_agreement_preview_available,
+ );
+ }, [countries, internalCountryCode]);
+
+ useEffect(() => {
+ setIncludeEmploymentAgreementPreview(isEmploymentAgreementPreviewAvailable);
+ }, [isEmploymentAgreementPreviewAvailable]);
const createEmploymentMutation = useCreateEmployment(options);
const updateEmploymentMutation = useUpdateEmployment(
@@ -577,6 +609,7 @@ export const useOnboarding = ({
engagementAgreementDetailsSchema?.fields || [],
contract_details: contractDetailsForm?.fields || [],
benefits: benefitOffersSchema?.fields || [],
+ employment_agreement_preview: [],
review: [],
}),
[
@@ -598,6 +631,7 @@ export const useOnboarding = ({
engagementAgreementDetailsSchema?.meta['x-jsf-fieldsets'],
contract_details: contractDetailsForm?.meta['x-jsf-fieldsets'],
benefits: null,
+ employment_agreement_preview: null,
review: null,
};
@@ -611,6 +645,7 @@ export const useOnboarding = ({
engagementAgreementDetailsSchema?.meta?.['x-jsf-presentation'],
contract_details: contractDetailsForm?.meta?.['x-jsf-presentation'],
benefits: benefitOffersSchema?.meta?.['x-jsf-presentation'],
+ employment_agreement_preview: null,
review: null,
};
@@ -707,6 +742,7 @@ export const useOnboarding = ({
)
: contractDetailsInitialValues,
benefits: benefitsInitialValues,
+ employment_agreement_preview: {},
};
}
return {
@@ -714,6 +750,7 @@ export const useOnboarding = ({
basic_information: basicInformationInitialValues,
contract_details: contractDetailsInitialValues,
benefits: benefitsInitialValues,
+ employment_agreement_preview: {},
};
}, [
selectCountryInitialValues,
@@ -792,6 +829,7 @@ export const useOnboarding = ({
stepFields.benefits,
{ skipMoneyConversion: true },
),
+ employment_agreement_preview: {},
};
setStepValues({
@@ -800,6 +838,7 @@ export const useOnboarding = ({
contract_details: contractDetailsInitialValues,
benefits: benefitsInitialValues,
engagement_agreement_details: engagementAgreementDetailsInitialValues,
+ employment_agreement_preview: {},
review: {},
});
diff --git a/src/flows/Onboarding/tests/utils.test.ts b/src/flows/Onboarding/tests/utils.test.ts
index 6d5c2302e..0acb07466 100644
--- a/src/flows/Onboarding/tests/utils.test.ts
+++ b/src/flows/Onboarding/tests/utils.test.ts
@@ -147,14 +147,11 @@ describe('buildSteps', () => {
describe('new dynamic behavior (useDynamicSteps: true)', () => {
it('should preserve original indices for all steps including hidden ones', () => {
- const { steps, stepsArray } = buildSteps({
+ const { stepsArray } = buildSteps({
includeSelectCountry: false,
useDynamicSteps: true,
});
- // All steps should be present, including hidden ones
- expect(stepsArray).toHaveLength(6);
-
// Hidden step should still be in the array with original index
expect(stepsArray[0]).toMatchObject({
name: 'select_country',
@@ -181,11 +178,23 @@ describe('buildSteps', () => {
visible: true,
});
- // Steps object should preserve original indices
- expect(steps.select_country.index).toBe(0);
- expect(steps.basic_information.index).toBe(1);
- expect(steps.contract_details.index).toBe(3);
- expect(steps.review.index).toBe(5);
+ expect(stepsArray[4]).toMatchObject({
+ name: 'benefits',
+ index: 4,
+ visible: true,
+ });
+
+ expect(stepsArray[5]).toMatchObject({
+ name: 'employment_agreement_preview',
+ index: 5,
+ visible: false,
+ });
+
+ expect(stepsArray[6]).toMatchObject({
+ name: 'review',
+ index: 6,
+ visible: true,
+ });
});
it('should include engagement_agreement_details when enabled', () => {
@@ -195,13 +204,26 @@ describe('buildSteps', () => {
useDynamicSteps: true,
});
- expect(stepsArray).toHaveLength(6);
expect(stepsArray[2]).toMatchObject({
name: 'engagement_agreement_details',
index: 2,
visible: true,
});
});
+
+ it('should include employment_agreement_preview when enabled', () => {
+ const { stepsArray } = buildSteps({
+ includeSelectCountry: true,
+ useEAPreview: true,
+ useDynamicSteps: true,
+ });
+
+ expect(stepsArray[5]).toMatchObject({
+ name: 'employment_agreement_preview',
+ index: 5,
+ visible: true,
+ });
+ });
});
describe('backwards compatibility', () => {
diff --git a/src/flows/Onboarding/types.ts b/src/flows/Onboarding/types.ts
index 0a4fe4f81..5084e0150 100644
--- a/src/flows/Onboarding/types.ts
+++ b/src/flows/Onboarding/types.ts
@@ -16,6 +16,7 @@ import { ReviewStep } from '@/src/flows/Onboarding/components/ReviewStep';
import { SaveDraftButton } from '@/src/flows/Onboarding/components/SaveDraftButton';
import { EngagementAgreementDetailsStep } from '@/src/flows/Onboarding/components/EngagementAgreementDetailsStep';
import { PreOnboardingRequirements } from '@/src/flows/Onboarding/components/PreOnboardingRequirements';
+import { PreviewEmploymentAgreementStep } from '@/src/flows/Onboarding/components/PreviewEmploymentAgreementStep';
export type OnboardingRenderProps = {
/**
@@ -40,6 +41,7 @@ export type OnboardingRenderProps = {
* @see {@link ReviewStep}
* @see {@link SaveDraftButton}
* @see {@link PreOnboardingRequirements}
+ * @see {@link PreviewEmploymentAgreementStep}
*/
components: {
SubmitButton: typeof OnboardingSubmit;
@@ -53,10 +55,14 @@ export type OnboardingRenderProps = {
ReviewStep: typeof ReviewStep;
SaveDraftButton: typeof SaveDraftButton;
PreOnboardingRequirements: typeof PreOnboardingRequirements;
+ PreviewEmploymentAgreementStep: typeof PreviewEmploymentAgreementStep;
};
};
-type OnboardingFeatures = 'onboarding_reserves' | 'dynamic_steps';
+type OnboardingFeatures =
+ | 'onboarding_reserves'
+ | 'dynamic_steps'
+ | 'ea_preview';
/**
* JSON schema version configuration for a specific country
diff --git a/src/flows/Onboarding/utils.ts b/src/flows/Onboarding/utils.ts
index 69b4057bf..0cdeeee45 100644
--- a/src/flows/Onboarding/utils.ts
+++ b/src/flows/Onboarding/utils.ts
@@ -7,12 +7,14 @@ export type StepKeys =
| 'engagement_agreement_details'
| 'contract_details'
| 'benefits'
+ | 'employment_agreement_preview'
| 'review';
type StepConfig = {
includeSelectCountry?: boolean;
includeEngagementAgreementDetails?: boolean;
useDynamicSteps?: boolean;
+ useEAPreview?: boolean;
};
export function buildSteps(config: StepConfig = {}) {
@@ -46,6 +48,11 @@ export function buildSteps(config: StepConfig = {}) {
label: 'Benefits',
visible: true,
},
+ {
+ name: 'employment_agreement_preview',
+ label: 'Preview Employment Agreement',
+ visible: Boolean(config?.useEAPreview),
+ },
{
name: 'review',
label: 'Review',