Skip to content

Commit

Permalink
Merge pull request #320 from ReseauEntourage/feature/EN-7350-Inscript…
Browse files Browse the repository at this point in the history
…ion-Case-Newsletter

[EN-7350] Onboarding - Add newsletter optin checkbox
  • Loading branch information
guillobits authored Aug 2, 2024
2 parents 4913b58 + 456c230 commit ac19d9f
Show file tree
Hide file tree
Showing 12 changed files with 94 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/components/backoffice/onboarding/Onboarding.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
} from 'src/utils';
import { FlattenedOnboardingFormData } from './Onboarding.types';

export const parseOnboadingFields = (
export const parseOnboadingProfileFields = (
fields: Partial<FlattenedOnboardingFormData>
): Partial<UserProfile> => {
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { FormSchema } from 'src/components/forms/FormSchema';

export const formOnboardingCandidateProfile: FormSchema<{
description: string;
optinNewsletter: boolean;
}> = {
id: 'form-onboarding-profile',
fields: [
Expand All @@ -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,
},
],
};
Original file line number Diff line number Diff line change
@@ -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: [
{
Expand All @@ -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,
},
],
};
11 changes: 7 additions & 4 deletions src/components/backoffice/onboarding/useOnboarding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -21,17 +21,20 @@ export const useOnboarding = () => {

const onSubmitLastStepOnboarding = useCallback(
(fields: Partial<FlattenedOnboardingFormData>) => {
const fieldsToSend = parseOnboadingFields(fields);
const profileFieldsToSend = parseOnboadingProfileFields(fields);
dispatch(
onboardingActions.validateLastStepOnboardingRequested(fieldsToSend)
onboardingActions.validateLastStepOnboardingRequested({
userProfile: profileFieldsToSend,
optinNewsletter: fields.optinNewsletter || false,
})
);
},
[dispatch]
);

const onSubmitFirstSecondStepOnboarding = useCallback(
(fields: Partial<FlattenedOnboardingFormData>) => {
const fieldsToSend = parseOnboadingFields(fields);
const fieldsToSend = parseOnboadingProfileFields(fields);
dispatch(
onboardingActions.validateFirstSecondStepOnboardingRequested(
fieldsToSend
Expand Down
14 changes: 14 additions & 0 deletions src/components/forms/FormSchema/FormSchema.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -45,6 +46,7 @@ export interface FormComponentValues<M extends boolean> {
[FormComponents.TEL_INPUT]: string;
[FormComponents.TEXTAREA]: string;
[FormComponents.CHECKBOX]: boolean;
[FormComponents.CHECKBOX_ALERT]: boolean;
[FormComponents.SELECT_SIMPLE]: string | number;
[FormComponents.SELECT]: MultiFilterConstant<M>;
[FormComponents.SELECT_CREATABLE]: MultiFilterConstant<M>;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -125,6 +132,7 @@ export type MultipleComponent = (typeof MultipleComponents)[number];
export type InputComponent =
| TextInputComponent
| CheckBoxComponent
| CheckBoxAlertComponent
| SelectComponent
| SelectRequestComponent
| SelectGraphicComponent
Expand Down Expand Up @@ -185,6 +193,11 @@ export interface FormFieldCheckBox<V extends FormSchemaValidation>
component: CheckBoxComponent;
}

export interface FormFieldCheckBoxAlert<V extends FormSchemaValidation>
extends FormFieldInputCommonProperties<V, CheckBoxAlertComponent> {
component: CheckBoxAlertComponent;
}

export interface FormFieldSelect<V extends FormSchemaValidation>
extends FormFieldInputCommonProperties<V, SelectComponent> {
component: SelectComponent;
Expand Down Expand Up @@ -262,6 +275,7 @@ export type FormFieldSelectRequest<V extends FormSchemaValidation> =
export type FormFieldInput<V extends FormSchemaValidation> = StrictUnion<
| FormFieldTextInput<V>
| FormFieldCheckBox<V>
| FormFieldCheckBoxAlert<V>
| FormFieldRadio<V>
| FormFieldSelectGraphic<V>
| FormFieldSelect<V>
Expand Down
13 changes: 13 additions & 0 deletions src/components/forms/FormSchema/FormSchema.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ import { AnyCantFix } from 'src/utils/Types';
import {
CheckBoxComponent,
CheckBoxComponents,
CheckBoxAlertComponents,
CheckBoxAlertComponent,
ExtractFormSchemaValidation,
FormComponent,
FormComponentValues,
FormField,
FormFieldCheckBox,
FormFieldCheckBoxAlert,
FormFieldGroup,
FormFieldMultiple,
FormFieldRadio,
Expand Down Expand Up @@ -96,6 +99,14 @@ export function isFormFieldCheckbox<S extends FormSchemaValidation>(
return CheckBoxComponents.includes(field.component as CheckBoxComponent);
}

export function isFormFieldCheckboxAlert<S extends FormSchemaValidation>(
field: FormField<S>
): field is FormFieldCheckBoxAlert<S> {
return CheckBoxAlertComponents.includes(
field.component as CheckBoxAlertComponent
);
}

export function isFormFieldSelect<S extends FormSchemaValidation>(
field: FormField<S>
): field is FormFieldSelect<S> {
Expand Down Expand Up @@ -130,12 +141,14 @@ export function isFormFieldInput<S extends FormSchemaValidation>(
| FormFieldRadio<S>
| FormFieldTextInput<S>
| FormFieldCheckBox<S>
| FormFieldCheckBoxAlert<S>
| FormFieldSelect<S>
| FormFieldSelectRequest<S>
| FormFieldSelectGraphic<S> {
return (
isFormFieldTextInput(field) ||
isFormFieldCheckbox(field) ||
isFormFieldCheckboxAlert(field) ||
isFormFieldRadio(field) ||
isFormFieldSelect(field) ||
isFormFieldSelectRequest(field) ||
Expand Down
9 changes: 9 additions & 0 deletions src/components/forms/fields/GenericField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
mapFieldRules,
Rule,
} from '../FormSchema';
import { Alert } from 'src/components/utils/Alert';
import {
CheckBox,
DatePicker,
Expand Down Expand Up @@ -208,6 +209,14 @@ export function GenericField<S extends FormSchema<AnyCantFix>>({
return <CheckBox {...commonProps} />;
}

if (field.component === 'checkbox-alert') {
return (
<Alert icon={null}>
<CheckBox {...commonProps} />
</Alert>
);
}

if (field.component === 'select-simple') {
const { options } = field;

Expand Down
3 changes: 2 additions & 1 deletion src/components/utils/Alert/Alert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ export const Alert = ({
closable = false,
visible = true,
onClose = () => {},
icon = <AlertIcon variant={variant} />,
}: AlertProps) => {
return (
<StyledAlert variant={variant} visible={visible}>
<AlertIcon variant={variant} />
{icon}
{children}
{closable && <ButtonIcon icon={<CloseIcon />} onClick={onClose} />}
</StyledAlert>
Expand Down
1 change: 1 addition & 0 deletions src/components/utils/Alert/Alert.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ export interface AlertProps {
closable?: boolean;
visible?: boolean;
onClose?: () => void;
icon?: React.ReactNode;
}
2 changes: 1 addition & 1 deletion src/components/utils/Inputs/CheckBox/CheckBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export function CheckBox({
<span className="checkmark" />
{title && <span className="label">{title}</span>}
</label>
{!useOutsideOfForm && <FieldErrorMessage error={error} />}
{!useOutsideOfForm && error && <FieldErrorMessage error={error} />}
</StyledCheckbox>
);
}
9 changes: 8 additions & 1 deletion src/use-cases/onboarding/onboarding.adapters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,11 @@ export const validateFirstSecondStepOnboardingAdapter = createRequestAdapter(

export const validateLastStepOnboardingAdapter = createRequestAdapter(
'validateLastStepOnboarding'
).withPayloads<Partial<UserProfile>, void, void>();
).withPayloads<
{
userProfile: Partial<UserProfile>;
optinNewsletter: boolean;
},
void,
void
>();
20 changes: 17 additions & 3 deletions src/use-cases/onboarding/onboarding.saga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,24 @@ export function* validateFirstSecondStepOnboardingSaga(
export function* validateLastStepOnboardingSaga(
action: ReturnType<typeof validateLastStepOnboardingRequested>
) {
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());
Expand Down

0 comments on commit ac19d9f

Please sign in to comment.