diff --git a/src/components/backoffice/onboarding/Onboarding.utils.ts b/src/components/backoffice/onboarding/Onboarding.utils.ts index fd6fbcaa3..88ddded06 100644 --- a/src/components/backoffice/onboarding/Onboarding.utils.ts +++ b/src/components/backoffice/onboarding/Onboarding.utils.ts @@ -5,7 +5,7 @@ import { } from 'src/utils'; import { FlattenedOnboardingFormData } from './Onboarding.types'; -export const parseOnboadingFields = ( +export const parseOnboadingProfileFields = ( fields: Partial ): Partial => { return { diff --git a/src/components/backoffice/onboarding/Onboarding/forms/schemas/formOnboardingCandidateProfile.ts b/src/components/backoffice/onboarding/Onboarding/forms/schemas/formOnboardingCandidateProfile.ts index 6c8685e4b..69bc30e78 100644 --- a/src/components/backoffice/onboarding/Onboarding/forms/schemas/formOnboardingCandidateProfile.ts +++ b/src/components/backoffice/onboarding/Onboarding/forms/schemas/formOnboardingCandidateProfile.ts @@ -2,6 +2,7 @@ import { FormSchema } from 'src/components/forms/FormSchema'; export const formOnboardingCandidateProfile: FormSchema<{ description: string; + optinNewsletter: boolean; }> = { id: 'form-onboarding-profile', fields: [ @@ -16,5 +17,13 @@ export const formOnboardingCandidateProfile: FormSchema<{ rows: 14, maxLines: { lines: 5, width: 655 }, }, + { + id: 'optinNewsletter', + name: 'optinNewsletter', + component: 'checkbox-alert', + title: + 'En cochant cette case, j’accepte de recevoir des informations et des actualités sur le programme entourage pro', + showLabel: true, + }, ], }; diff --git a/src/components/backoffice/onboarding/Onboarding/forms/schemas/formOnboardingCoachProfile.ts b/src/components/backoffice/onboarding/Onboarding/forms/schemas/formOnboardingCoachProfile.ts index fbc0f2930..1145fb230 100644 --- a/src/components/backoffice/onboarding/Onboarding/forms/schemas/formOnboardingCoachProfile.ts +++ b/src/components/backoffice/onboarding/Onboarding/forms/schemas/formOnboardingCoachProfile.ts @@ -1,6 +1,9 @@ import { FormSchema } from 'src/components/forms/FormSchema'; -export const formOnboardingCoachProfile: FormSchema<{ description: string }> = { +export const formOnboardingCoachProfile: FormSchema<{ + description: string; + optinNewsletter: boolean; +}> = { id: 'form-onboarding-profile', fields: [ { @@ -14,5 +17,13 @@ export const formOnboardingCoachProfile: FormSchema<{ description: string }> = { rows: 14, maxLines: { lines: 5, width: 655 }, }, + { + id: 'optinNewsletter', + name: 'optinNewsletter', + component: 'checkbox-alert', + title: + 'En cochant cette case, j’accepte de recevoir des informations et des actualités sur le programme entourage pro', + showLabel: true, + }, ], }; diff --git a/src/components/backoffice/onboarding/useOnboarding.ts b/src/components/backoffice/onboarding/useOnboarding.ts index 3854e03b4..326bdbb40 100644 --- a/src/components/backoffice/onboarding/useOnboarding.ts +++ b/src/components/backoffice/onboarding/useOnboarding.ts @@ -8,7 +8,7 @@ import { validateLastStepOnboardingSelectors, } from 'src/use-cases/onboarding'; import { FlattenedOnboardingFormData } from './Onboarding.types'; -import { parseOnboadingFields } from './Onboarding.utils'; +import { parseOnboadingProfileFields } from './Onboarding.utils'; export const useOnboarding = () => { const dispatch = useDispatch(); @@ -21,9 +21,12 @@ export const useOnboarding = () => { const onSubmitLastStepOnboarding = useCallback( (fields: Partial) => { - const fieldsToSend = parseOnboadingFields(fields); + const profileFieldsToSend = parseOnboadingProfileFields(fields); dispatch( - onboardingActions.validateLastStepOnboardingRequested(fieldsToSend) + onboardingActions.validateLastStepOnboardingRequested({ + userProfile: profileFieldsToSend, + optinNewsletter: fields.optinNewsletter || false, + }) ); }, [dispatch] @@ -31,7 +34,7 @@ export const useOnboarding = () => { const onSubmitFirstSecondStepOnboarding = useCallback( (fields: Partial) => { - const fieldsToSend = parseOnboadingFields(fields); + const fieldsToSend = parseOnboadingProfileFields(fields); dispatch( onboardingActions.validateFirstSecondStepOnboardingRequested( fieldsToSend diff --git a/src/components/forms/FormSchema/FormSchema.types.ts b/src/components/forms/FormSchema/FormSchema.types.ts index 400ccf161..03d8ba1fa 100644 --- a/src/components/forms/FormSchema/FormSchema.types.ts +++ b/src/components/forms/FormSchema/FormSchema.types.ts @@ -10,6 +10,7 @@ export const FormComponents = { TEL_INPUT: 'tel-input', TEXTAREA: 'textarea', CHECKBOX: 'checkbox', + CHECKBOX_ALERT: 'checkbox-alert', SELECT_SIMPLE: 'select-simple', SELECT: 'select', SELECT_CREATABLE: 'select-creatable', @@ -45,6 +46,7 @@ export interface FormComponentValues { [FormComponents.TEL_INPUT]: string; [FormComponents.TEXTAREA]: string; [FormComponents.CHECKBOX]: boolean; + [FormComponents.CHECKBOX_ALERT]: boolean; [FormComponents.SELECT_SIMPLE]: string | number; [FormComponents.SELECT]: MultiFilterConstant; [FormComponents.SELECT_CREATABLE]: MultiFilterConstant; @@ -79,6 +81,11 @@ export type TextInputComponent = (typeof TextInputComponents)[number]; export const CheckBoxComponents = [FormComponents.CHECKBOX] as const; export type CheckBoxComponent = (typeof CheckBoxComponents)[number]; + +export const CheckBoxAlertComponents = [FormComponents.CHECKBOX_ALERT] as const; + +export type CheckBoxAlertComponent = (typeof CheckBoxAlertComponents)[number]; + export const SelectRequestComponents = [ FormComponents.SELECT, FormComponents.SELECT_CREATABLE, @@ -125,6 +132,7 @@ export type MultipleComponent = (typeof MultipleComponents)[number]; export type InputComponent = | TextInputComponent | CheckBoxComponent + | CheckBoxAlertComponent | SelectComponent | SelectRequestComponent | SelectGraphicComponent @@ -185,6 +193,11 @@ export interface FormFieldCheckBox component: CheckBoxComponent; } +export interface FormFieldCheckBoxAlert + extends FormFieldInputCommonProperties { + component: CheckBoxAlertComponent; +} + export interface FormFieldSelect extends FormFieldInputCommonProperties { component: SelectComponent; @@ -262,6 +275,7 @@ export type FormFieldSelectRequest = export type FormFieldInput = StrictUnion< | FormFieldTextInput | FormFieldCheckBox + | FormFieldCheckBoxAlert | FormFieldRadio | FormFieldSelectGraphic | FormFieldSelect diff --git a/src/components/forms/FormSchema/FormSchema.utils.ts b/src/components/forms/FormSchema/FormSchema.utils.ts index e83ea8604..227f1096b 100644 --- a/src/components/forms/FormSchema/FormSchema.utils.ts +++ b/src/components/forms/FormSchema/FormSchema.utils.ts @@ -3,11 +3,14 @@ import { AnyCantFix } from 'src/utils/Types'; import { CheckBoxComponent, CheckBoxComponents, + CheckBoxAlertComponents, + CheckBoxAlertComponent, ExtractFormSchemaValidation, FormComponent, FormComponentValues, FormField, FormFieldCheckBox, + FormFieldCheckBoxAlert, FormFieldGroup, FormFieldMultiple, FormFieldRadio, @@ -96,6 +99,14 @@ export function isFormFieldCheckbox( return CheckBoxComponents.includes(field.component as CheckBoxComponent); } +export function isFormFieldCheckboxAlert( + field: FormField +): field is FormFieldCheckBoxAlert { + return CheckBoxAlertComponents.includes( + field.component as CheckBoxAlertComponent + ); +} + export function isFormFieldSelect( field: FormField ): field is FormFieldSelect { @@ -130,12 +141,14 @@ export function isFormFieldInput( | FormFieldRadio | FormFieldTextInput | FormFieldCheckBox + | FormFieldCheckBoxAlert | FormFieldSelect | FormFieldSelectRequest | FormFieldSelectGraphic { return ( isFormFieldTextInput(field) || isFormFieldCheckbox(field) || + isFormFieldCheckboxAlert(field) || isFormFieldRadio(field) || isFormFieldSelect(field) || isFormFieldSelectRequest(field) || diff --git a/src/components/forms/fields/GenericField.tsx b/src/components/forms/fields/GenericField.tsx index ea082a6b6..e4bad2d62 100644 --- a/src/components/forms/fields/GenericField.tsx +++ b/src/components/forms/fields/GenericField.tsx @@ -21,6 +21,7 @@ import { mapFieldRules, Rule, } from '../FormSchema'; +import { Alert } from 'src/components/utils/Alert'; import { CheckBox, DatePicker, @@ -208,6 +209,14 @@ export function GenericField>({ return ; } + if (field.component === 'checkbox-alert') { + return ( + + + + ); + } + if (field.component === 'select-simple') { const { options } = field; diff --git a/src/components/utils/Alert/Alert.tsx b/src/components/utils/Alert/Alert.tsx index fb5b78fff..8cd286180 100644 --- a/src/components/utils/Alert/Alert.tsx +++ b/src/components/utils/Alert/Alert.tsx @@ -19,10 +19,11 @@ export const Alert = ({ closable = false, visible = true, onClose = () => {}, + icon = , }: AlertProps) => { return ( - + {icon} {children} {closable && } onClick={onClose} />} diff --git a/src/components/utils/Alert/Alert.types.ts b/src/components/utils/Alert/Alert.types.ts index 28f42e421..6ecca4508 100644 --- a/src/components/utils/Alert/Alert.types.ts +++ b/src/components/utils/Alert/Alert.types.ts @@ -6,4 +6,5 @@ export interface AlertProps { closable?: boolean; visible?: boolean; onClose?: () => void; + icon?: React.ReactNode; } diff --git a/src/components/utils/Inputs/CheckBox/CheckBox.tsx b/src/components/utils/Inputs/CheckBox/CheckBox.tsx index f82ade31a..2f73b6f56 100644 --- a/src/components/utils/Inputs/CheckBox/CheckBox.tsx +++ b/src/components/utils/Inputs/CheckBox/CheckBox.tsx @@ -50,7 +50,7 @@ export function CheckBox({ {title && {title}} - {!useOutsideOfForm && } + {!useOutsideOfForm && error && } ); } diff --git a/src/use-cases/onboarding/onboarding.adapters.ts b/src/use-cases/onboarding/onboarding.adapters.ts index ae318bb84..cc805ed3d 100644 --- a/src/use-cases/onboarding/onboarding.adapters.ts +++ b/src/use-cases/onboarding/onboarding.adapters.ts @@ -7,4 +7,11 @@ export const validateFirstSecondStepOnboardingAdapter = createRequestAdapter( export const validateLastStepOnboardingAdapter = createRequestAdapter( 'validateLastStepOnboarding' -).withPayloads, void, void>(); +).withPayloads< + { + userProfile: Partial; + optinNewsletter: boolean; + }, + void, + void +>(); diff --git a/src/use-cases/onboarding/onboarding.saga.ts b/src/use-cases/onboarding/onboarding.saga.ts index 860b3fcae..d330843a3 100644 --- a/src/use-cases/onboarding/onboarding.saga.ts +++ b/src/use-cases/onboarding/onboarding.saga.ts @@ -78,10 +78,24 @@ export function* validateFirstSecondStepOnboardingSaga( export function* validateLastStepOnboardingSaga( action: ReturnType ) { - const userId = yield* select(selectCurrentUserId); - const userProfile = action.payload; + const user = yield* select(selectAuthenticatedUser); + const { userProfile, optinNewsletter } = action.payload; + try { - yield* call(() => Api.putUserProfile(userId, userProfile)); + // Update user profile with new data + yield* call(() => Api.putUserProfile(user.id, userProfile)); + + // If user optin for newsletter, call api to set OK to receive newsletter + if (optinNewsletter) { + // Call api to set OK to receive newsletter + yield* call(() => { + Api.postNewsletter({ + email: user.email, + zone: user.zone, + status: user.candidat ? 'CANDIDAT' : 'PARTICULIER', + }); + }); + } yield* put(validateLastStepOnboardingSucceeded()); yield* put(currentUserActions.fetchUserRequested()); yield* put(endOnboarding());