Skip to content

Commit

Permalink
Started migration of form-sections components to TypeScript
Browse files Browse the repository at this point in the history
  • Loading branch information
Pierre-Eric Garcia committed Aug 16, 2023
1 parent 173bd38 commit ea86a1b
Show file tree
Hide file tree
Showing 20 changed files with 128 additions and 55 deletions.
2 changes: 2 additions & 0 deletions frontend/src/components/atoms/hyperTexts/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
download?: boolean;
submit?: boolean;
children?: React.ReactNode;
target?: string;
rel?: string;
}

const Button: React.FC<ButtonProps> = ({
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/atoms/inputs/RadioInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Label from './Label';
import { InputProps } from './Input';

interface RadioInputProps extends InputProps {
options?: { id: string; label: string }[];
options?: { id: string | number; label: string }[];
}

export const RadioInput: React.FC<RadioInputProps> = ({
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/components/atoms/inputs/SelectInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import SideBySideWrapper from './SideBySideWrapper';
import Label from './Label';

interface SelectInputProps extends SelectHTMLAttributes<HTMLSelectElement> {
options?: { id: string; label: string }[];
options?: { id: string | number; label: string }[];
useOtherOption?: boolean;
label: string;
helper: string;
meta: string;
label: string | React.ReactNode;
helper?: string;
meta?: string;
}

export const SelectInput: React.FC<SelectInputProps> = ({
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/molecules/Stepper/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import './style.css';
import { useDataProviderConfigurations } from '../../templates/hooks/use-data-provider-configurations';

type StepperProps = {
children: React.ReactNode;
children?: React.ReactNode;
steps: string[];
currentStep: string | null;
previousStepNotCompleted?: boolean;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
import { MouseEventHandler } from 'react';
import ConfirmationModal from '../../ConfirmationModal';

export const DisconnectionModal = ({ disconnectionUrl, handleCancel }) => {
type DisconnectionModalProps = {
disconnectionUrl: string;
handleCancel: MouseEventHandler<HTMLElement>;
};

export const DisconnectionModal: React.FC<DisconnectionModalProps> = ({
disconnectionUrl,
handleCancel,
}) => {
return (
<ConfirmationModal
title="Vous allez être déconnecté"
handleConfirm={() => (window.location = disconnectionUrl)}
handleConfirm={() => (window.location.href = disconnectionUrl)}
handleCancel={handleCancel}
>
Afin de mettre à jour vos informations personnelles, vous allez être
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { isEmpty } from 'lodash';
import { useCallback, useContext, useEffect, useState } from 'react';
import { isValidNAFCode } from '../../../../lib';
import { getCachedOrganizationInformation } from '../../../../services/external';
import Alert from '../../../atoms/Alert';
import Alert, { AlertType } from '../../../atoms/Alert';
import Button from '../../../atoms/hyperTexts/Button';
import Loader from '../../../atoms/Loader';
import { Card, CardHead } from '../../../molecules/Card';
Expand Down Expand Up @@ -43,7 +43,13 @@ export const OrganisationCard = () => {
const { user, isLoading } = useAuth();

const updateOrganizationInfo = useCallback(
({ organization_id, siret }) => {
({
organization_id,
siret,
}: {
organization_id: number;
siret: string;
}) => {
onChange({
target: {
name: 'organization_id',
Expand All @@ -63,7 +69,8 @@ export const OrganisationCard = () => {
!isUserEnrollmentLoading &&
!disabled &&
!organization_id &&
!isEmpty(user.organizations)
user?.organizations &&
user.organizations.length > 0
) {
updateOrganizationInfo({
organization_id: user.organizations[0].id,
Expand All @@ -79,7 +86,7 @@ export const OrganisationCard = () => {
]);

useEffect(() => {
const fetchOrganizationInfo = async (siret) => {
const fetchOrganizationInfo = async (siret: string) => {
try {
setIsOrganizationInfoLoading(true);
const {
Expand Down Expand Up @@ -131,14 +138,14 @@ export const OrganisationCard = () => {
}
}, [siret]);

const onOrganizationChange = (new_organization_id) => {
const onOrganizationChange = (new_organization_id: number) => {
setShowOrganizationPrompt(false);

if (!isEmpty(user.organizations)) {
if (!isEmpty(user?.organizations)) {
updateOrganizationInfo({
organization_id: new_organization_id,
siret: user.organizations.find((o) => o.id === new_organization_id)
.siret,
siret: user?.organizations?.find((o) => o.id === new_organization_id)
?.siret as string,
});
}
};
Expand All @@ -157,21 +164,21 @@ export const OrganisationCard = () => {
<h3>Vous faites cette demande pour</h3>
{activite && !isValidNAFCode(target_api, activite) && (
<div className="fr-mb-1w">
<Alert type="warning">
<Alert type={AlertType.warning}>
Votre organisme ne semble pas être éligible
</Alert>
</div>
)}
{showOrganizationInfoNotFound && (
<div className="fr-mb-1w">
<Alert type="warning">
<Alert type={AlertType.warning}>
Cet établissement est fermé ou le SIRET est invalide.
</Alert>
</div>
)}
{showOrganizationInfoError && (
<div className="fr-mb-1w">
<Alert type="error">
<Alert type={AlertType.error}>
Erreur inconnue lors de la récupération des informations de cet
établissement.
</Alert>
Expand Down Expand Up @@ -215,7 +222,7 @@ export const OrganisationCard = () => {
onSelect={onOrganizationChange}
onJoinOrganization={onJoinOrganization}
onClose={() => setShowOrganizationPrompt(false)}
organizations={user.organizations}
organizations={user?.organizations}
/>
)}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
import React, { useMemo } from 'react';
import React, { ChangeEventHandler, useMemo } from 'react';
import RadioInput from '../../../atoms/inputs/RadioInput';
import ConfirmationModal from '../../ConfirmationModal';
import { User } from '../../../templates/InstructorEnrollmentList';

const OrganizationPrompt = ({
type OrganizationPromptProps = {
selectedOrganizationId: number;
onSelect: Function;
onClose: Function;
onJoinOrganization: Function;
organizations: User['organizations'];
};

const OrganizationPrompt: React.FC<OrganizationPromptProps> = ({
selectedOrganizationId,
onSelect,
onClose,
onJoinOrganization,
organizations,
}) => {
const onChange = ({ target: { value } }) => onSelect(parseInt(value));
const onChange: ChangeEventHandler<HTMLInputElement> = ({
target: { value },
}) => onSelect(parseInt(value));

const options = useMemo(
() =>
organizations.map(({ id, label, siret }) => ({
organizations?.map(({ id, label, siret }) => ({
id,
label: label || siret,
})),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,19 @@ export const PersonalInformationCard = () => {

const { isLoading } = useAuth();

const [personalInformation, setPersonalInformation] = useState({});
const [personalInformation, setPersonalInformation] = useState<{
given_name: string;
family_name: string;
email: string;
phone_number: string;
job: string;
} | null>(null);
const [showDisconnectionPrompt, setShowDisconnectionPrompt] = useState(false);

useEffect(() => {
const firstDemandeur =
!isEmpty(team_members) &&
team_members.find(({ type }) => type === 'demandeur');
team_members.find(({ type }: { type: string }) => type === 'demandeur');
if (firstDemandeur) {
// note that they might be more than one demandeur
// for now we just display the first demandeur found
Expand All @@ -38,7 +44,7 @@ export const PersonalInformationCard = () => {
<h3>Vous êtes</h3>
<CardHead>
<b>
{personalInformation.given_name} {personalInformation.family_name}
{personalInformation?.given_name} {personalInformation?.family_name}
</b>
{!disabled && (
<Button
Expand All @@ -50,11 +56,13 @@ export const PersonalInformationCard = () => {
)}
</CardHead>
<div>
{personalInformation.email}
<CopyToClipboardButton textToCopy={personalInformation.email} />
{personalInformation?.email}
<CopyToClipboardButton
textToCopy={personalInformation?.email as string}
/>
</div>
<div>{personalInformation.phone_number}</div>
<div>{personalInformation.job}</div>
<div>{personalInformation?.phone_number}</div>
<div>{personalInformation?.job}</div>

{!disabled && !isLoading && showDisconnectionPrompt && (
<DisconnectionModal
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { isNumber } from 'lodash';
import React, { useContext, useEffect, useMemo } from 'react';
import React, {
ChangeEventHandler,
useContext,
useEffect,
useMemo,
} from 'react';
import Alert from '../../../atoms/Alert';
import Button from '../../../atoms/hyperTexts/Button';
import Link from '../../../atoms/hyperTexts/Link';
Expand All @@ -16,7 +21,15 @@ const typeOptions = [
{ id: 'other', label: 'Autre' },
];

export const TechnicalTeamCard = ({ editorList = [], sectionIndex }) => {
type TechnicalTeamCardProps = {
editorList: { siret: string; name: string }[];
sectionIndex: number;
};

export const TechnicalTeamCard: React.FC<TechnicalTeamCardProps> = ({
editorList = [],
sectionIndex,
}) => {
const {
disabled,
onChange,
Expand Down Expand Up @@ -68,7 +81,9 @@ export const TechnicalTeamCard = ({ editorList = [], sectionIndex }) => {
});
};

const onTypeChange = ({ target: { value } }) => {
const onTypeChange: ChangeEventHandler<HTMLInputElement> = ({
target: { value },
}) => {
onChange({
target: { name: 'technical_team_type', value },
});
Expand All @@ -84,7 +99,9 @@ export const TechnicalTeamCard = ({ editorList = [], sectionIndex }) => {
[editorList, technical_team_value]
);

const onValueChange = ({ target: { value: valueLabel } }) => {
const onValueChange: ChangeEventHandler<HTMLInputElement> = ({
target: { value: valueLabel },
}) => {
const value =
editorList.find(({ name }) => name === valueLabel)?.siret || valueLabel;

Expand Down Expand Up @@ -129,7 +146,7 @@ export const TechnicalTeamCard = ({ editorList = [], sectionIndex }) => {
)}
<RadioInput
label="Qui s’occupera des aspects techniques et informatiques ?"
options={[{ id: '', label: selectedTypeLabel }]}
options={[{ id: '', label: selectedTypeLabel as string }]}
name="technical_team_type"
value=""
disabled={disabled}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,25 @@ import SelectInput from '../../../atoms/inputs/SelectInput';
import ExpandableQuote from '../../../molecules/ExpandableQuote';
import { isEmpty } from 'lodash';
import { ScrollablePanel } from '../../Scrollable';
import Alert from '../../../atoms/Alert';
import Alert, { AlertType } from '../../../atoms/Alert';
import Link from '../../../atoms/hyperTexts/Link';
import { Enrollment } from '../../../templates/InstructorEnrollmentList';

const SECTION_LABEL = 'Habilitation associée';
const SECTION_ID = encodeURIComponent(SECTION_LABEL);

const PreviousEnrollmentSection = ({ steps }) => {
type PreviousEnrollmentSectionProps = {
steps: string[];
};

interface PreviousEnrollmentSectionType
extends React.FC<PreviousEnrollmentSectionProps> {
sectionLabel: string;
}

const PreviousEnrollmentSection: PreviousEnrollmentSectionType = ({
steps,
}) => {
const {
isUserEnrollmentLoading,
disabled,
Expand All @@ -28,12 +40,14 @@ const PreviousEnrollmentSection = ({ steps }) => {
disabled && !isUserEnrollmentLoading && previous_enrollment_id
);

const [validatedEnrollments, setValidatedEnrollments] = useState([]);
const [validatedEnrollments, setValidatedEnrollments] = useState<
Enrollment[]
>([]);
const [isValidatedEnrollmentsLoading, setIsValidatedEnrollmentsLoading] =
useState(false);
const [validatedEnrollmentsError, setValidatedEnrollmentsError] =
useState(false);
const [previousTargetApi, setPreviousTargetApi] = useState();
const [previousTargetApi, setPreviousTargetApi] = useState<string | null>();

const { label: targetApiLabel } = useDataProvider(target_api);
const { label: previousTargetApiLabel } = useDataProvider(previousTargetApi);
Expand All @@ -50,7 +64,7 @@ const PreviousEnrollmentSection = ({ steps }) => {
setIsValidatedEnrollmentsLoading(true);
setValidatedEnrollmentsError(false);
const enrollments = await getUserValidatedEnrollments(
previousTargetApi
previousTargetApi as string
);
setValidatedEnrollments(enrollments);
setIsValidatedEnrollmentsLoading(false);
Expand Down Expand Up @@ -90,7 +104,7 @@ const PreviousEnrollmentSection = ({ steps }) => {
currentStep={!isValidatedEnrollmentsLoading && target_api}
previousStepNotCompleted={
!isValidatedEnrollmentsLoading &&
previousTargetApi &&
!!previousTargetApi &&
validatedEnrollments.length === 0
}
/>
Expand All @@ -101,7 +115,7 @@ const PreviousEnrollmentSection = ({ steps }) => {
!isValidatedEnrollmentsLoading &&
previousTargetApi &&
validatedEnrollments.length === 0 && (
<Alert type="warning">
<Alert type={AlertType.warning}>
<p>
Pour demander l’accès à <b>{targetApiLabel}</b>, vous devez avoir
préalablement obtenu une habilitation à{' '}
Expand All @@ -112,8 +126,8 @@ const PreviousEnrollmentSection = ({ steps }) => {
<ReactRouterLink
to={{
pathname: `/${previousTargetApi.replace(/_/g, '-')}`,
state: { fromFranceConnectedAPI: target_api },
}}
state={{ fromFranceConnectedAPI: target_api }}
>
demander votre habilitation à <b>{previousTargetApiLabel}</b>
</ReactRouterLink>{' '}
Expand Down Expand Up @@ -160,7 +174,7 @@ const PreviousEnrollmentSection = ({ steps }) => {
</>
)}
{!disabled && !isUserEnrollmentLoading && validatedEnrollmentsError && (
<Alert title="Erreur" type="error">
<Alert title="Erreur" type={AlertType.error}>
Erreur inconnue lors de la récupération de vos habilitations{' '}
{previousTargetApiLabel}.
</Alert>
Expand Down
Loading

0 comments on commit ea86a1b

Please sign in to comment.