Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[tra-15398]Mettre au DSFR la modale de signature de l'émetteur #3786

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,6 @@
}

.JourneyStopName {
font-size: 0.875rem !important;
line-height: 1.5rem !important;
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ interface JourneyStopNameProps {
}

export function JourneyStopName({ children }: JourneyStopNameProps) {
return <strong className={styles.JourneyStopName}>{children}</strong>;
return <p className={styles.JourneyStopName}>{children}</p>;
}

interface JourneyStopDescriptionProps {
Expand All @@ -45,5 +45,5 @@ interface JourneyStopDescriptionProps {
export function JourneyStopDescription({
children
}: JourneyStopDescriptionProps) {
return <p>{children}</p>;
return <p className="fr-text--bold">{children}</p>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
JourneyStop,
JourneyStopName,
JourneyStopDescription
} from "../../../../../common/components";
} from "../../../../common/components";

interface Props {
bsvhu: Bsvhu;
Expand All @@ -17,7 +17,7 @@ export function BsvhuJourneySummary({ bsvhu }: Props) {
<JourneyStop
variant={bsvhu.emitter?.emission?.signature ? "complete" : "active"}
>
<JourneyStopName>Émetteur</JourneyStopName>
<JourneyStopName>Producteur</JourneyStopName>
<JourneyStopDescription>
{bsvhu.emitter?.company?.name} ({bsvhu.emitter?.company?.siret})<br />
{bsvhu.emitter?.company?.address}
Expand Down
180 changes: 180 additions & 0 deletions front/src/Apps/Dashboard/Validation/Bsvhu/SignVhuEmission.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
import { useMutation, useQuery } from "@apollo/client";
import Button from "@codegouvfr/react-dsfr/Button";
import Input from "@codegouvfr/react-dsfr/Input";
import { zodResolver } from "@hookform/resolvers/zod";
import {
Mutation,
MutationSignBsvhuArgs,
Query,
QueryBsvhuArgs,
SignatureTypeInput
} from "@td/codegen-ui";
import { subMonths } from "date-fns";
import React from "react";
import { useForm } from "react-hook-form";
import { generatePath, Link, useLocation, useParams } from "react-router-dom";
import { z } from "zod";
import { datetimeToYYYYMMDD } from "../../../../common/datetime";
import { Loader } from "../../../common/Components";
import { DsfrNotificationError } from "../../../common/Components/Error/Error";
import TdModal from "../../../common/Components/Modal/Modal";
import {
GET_VHU_FORM,
SIGN_BSVHU
} from "../../../common/queries/bsvhu/queries";
import routes from "../../../routes";
import { BsvhuJourneySummary } from "./BsvhuJourneySummary";
import WasteVhuSummary from "./WasteVhuSummary";

const schema = z.object({
author: z
.string()
.min(3, "Le nom et prénom de l'auteur de la signature est requis"),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quitte à exiger un nom et un prénom, est-ce qu'on peut pas ajouter une validation comme quoi il y a au moins 2 mots? Je sais qu'il n'y a pas cette vérif côté API, mais ça empêche pas de rendre ça plus carré côté front

date: z.coerce
.date({
required_error: "La date d'émission est requise",
invalid_type_error: "Format de date invalide."
})
.transform(v => v?.toISOString())
});
export type ZodBsvhuEmission = z.infer<typeof schema>;

const SignVhuEmission = ({ bsvhuId, onClose }) => {
const { siret } = useParams<{ siret: string }>();
const location = useLocation();

const { data } = useQuery<Pick<Query, "bsvhu">, QueryBsvhuArgs>(
GET_VHU_FORM,
{
variables: {
id: bsvhuId
}
}
);

const [signBsvhu, { loading, error }] = useMutation<
Pick<Mutation, "signBsvhu">,
MutationSignBsvhuArgs
>(SIGN_BSVHU);

const title = "Signer le bordereau";
const TODAY = new Date();

const initialState = {
date: datetimeToYYYYMMDD(TODAY),
author: ""
};

const { handleSubmit, reset, formState, register } =
useForm<ZodBsvhuEmission>({
values: initialState,
resolver: async (data, context, options) => {
return zodResolver(schema)(data, context, options);
}
});

if (data == null) {
return <Loader />;
}

const { bsvhu } = data;

const onCancel = () => {
reset();
onClose();
};

return (
<TdModal onClose={onClose} title={title} ariaLabel={title} isOpen size="L">
{bsvhu.metadata?.errors?.some(
error => error.requiredFor === SignatureTypeInput.Emission
) ? (
<>
<p className="tw-mt-2 tw-text-red-700">
Vous devez mettre à jour le bordereau et renseigner les champs
obligatoires avant de le signer.
</p>
<ul className="tw-mb-2 tw-text-red-700 tw-list-disc">
{bsvhu.metadata?.errors.map((error, idx) => (
<li key={idx}>{error.message}</li>
))}
</ul>
<Link
to={generatePath(routes.dashboard.bsvhus.edit, {
siret,
id: bsvhu.id
})}
className="btn btn--primary"
state={{ background: location }}
>
Mettre le bordereau à jour pour le signer
</Link>
</>
) : (
<>
<WasteVhuSummary bsvhu={bsvhu} />
<BsvhuJourneySummary bsvhu={bsvhu} />

<p className="fr-text fr-mb-2w">
En qualité <strong>d'émetteur du déchet</strong>, j'atteste que les
informations ci-dessus sont correctes. En signant ce document,
j'autorise le transporteur à prendre en charge le déchet.
</p>

<form
onSubmit={handleSubmit(async data => {
await signBsvhu({
variables: {
id: bsvhu.id,
input: {
...data,
type: SignatureTypeInput.Emission
}
}
});
onClose();
})}
>
<div className="fr-col-4 fr-mb-2w">
<Input
label="Date de prise en charge"
nativeInputProps={{
type: "date",
min: datetimeToYYYYMMDD(subMonths(TODAY, 2)),
max: datetimeToYYYYMMDD(TODAY),
...register("date")
}}
state={formState.errors.date ? "error" : "default"}
stateRelatedMessage={formState.errors.date?.message}
/>
</div>
<div className="fr-col-8 fr-mb-2w">
<Input
label="Nom et prénom"
state={formState.errors.author ? "error" : "default"}
nativeInputProps={{
...register("author")
}}
stateRelatedMessage={formState.errors.author?.message}
/>
</div>
<div className="fr-mb-8w">
{error && <DsfrNotificationError apolloError={error} />}
</div>

<div className="fr-modal__footer">
<div className="fr-btns-group fr-btns-group--right fr-btns-group--inline fr-btns-group--icon-left">
<Button type="button" priority="secondary" onClick={onCancel}>
Annuler
</Button>
<Button disabled={loading}>Signer</Button>
</div>
</div>
</form>
</>
)}
</TdModal>
);
};

export default SignVhuEmission;
50 changes: 50 additions & 0 deletions front/src/Apps/Dashboard/Validation/Bsvhu/WasteVhuSummary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Bsvhu, BsvhuPackaging } from "@td/codegen-ui";
import * as React from "react";
import {
DsfrDataList,
DsfrDataListDescription,
DsfrDataListItem,
DsfrDataListTerm
} from "../../../../common/components";
import { isDangerous } from "@td/constants";

interface WasteVhuSummaryProps {
bsvhu: Bsvhu;
}
const WasteVhuSummary = ({ bsvhu }: WasteVhuSummaryProps) => {
const isDangerousWaste = isDangerous(bsvhu.wasteCode ?? "");
const usualName = isDangerousWaste ? "VHU pollué" : "VHU dépollué";
return (
<DsfrDataList>
<DsfrDataListItem>
<DsfrDataListTerm>BSVHU n°</DsfrDataListTerm>
<DsfrDataListDescription>{bsvhu.id}</DsfrDataListDescription>
</DsfrDataListItem>
<DsfrDataListItem>
<DsfrDataListTerm>Code déchet</DsfrDataListTerm>
<DsfrDataListDescription>{bsvhu.wasteCode}</DsfrDataListDescription>
</DsfrDataListItem>
<DsfrDataListItem>
<DsfrDataListTerm>Nom usuel du déchet</DsfrDataListTerm>
<DsfrDataListDescription>{usualName}</DsfrDataListDescription>
</DsfrDataListItem>
<DsfrDataListItem>
<DsfrDataListTerm>
{bsvhu.packaging === BsvhuPackaging.Lot
? "Nombre de lot(s)"
: "Nombre d'unité(s)"}
</DsfrDataListTerm>
<DsfrDataListDescription>{bsvhu.quantity}</DsfrDataListDescription>
</DsfrDataListItem>
<DsfrDataListItem>
<DsfrDataListTerm>
{bsvhu.weight?.isEstimate ? "Poids estimé" : "Poids réel"}
</DsfrDataListTerm>
<DsfrDataListDescription>
{`${bsvhu.weight?.value}t`}
</DsfrDataListDescription>
</DsfrDataListItem>
</DsfrDataList>
);
};
export default WasteVhuSummary;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";
import { Bsvhu, BsvhuStatus } from "@td/codegen-ui";
import { SignEmission } from "../../../../../dashboard/components/BSDList/BSVhu/WorkflowAction/SignEmission";
import SignVhuEmission from "../../Bsvhu/SignVhuEmission";
import { SignTransport } from "../../../../../dashboard/components/BSDList/BSVhu/WorkflowAction/SignTransport";
import { SignOperation } from "../../../../../dashboard/components/BSDList/BSVhu/WorkflowAction/SignOperation";

Expand All @@ -23,13 +23,7 @@ const ActBsvhuValidation = ({
};

const renderInitialModal = () => {
return (
<SignEmission
bsvhuId={bsd.id}
siret={currentSiret}
{...actionButtonAdapterProps}
/>
);
return <SignVhuEmission bsvhuId={bsd.id} onClose={onClose} />;
};

const renderSignedByProducerModal = () => {
Expand Down
2 changes: 1 addition & 1 deletion front/src/common/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export * from "./Label";
export * from "./Slideshow";
export * from "./List";
export * from "./Table";
export * from "./Journey";
export * from "../../Apps/Dashboard/Components/Journey/Journey";
export * from "../../Apps/common/Components/Journey/DsfrJourney";
export * from "./DataList";
export * from "../../Apps/common/Components/DataList/DsfrDataList";
Expand Down
4 changes: 4 additions & 0 deletions front/src/common/datetime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,7 @@ export function formatDateTime(date: Props): string {
locale: fr
});
}

// YYYY-MM-DD
export const datetimeToYYYYMMDD = (dt: Date): string =>
format(new Date(dt), "yyyy-MM-dd");
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from "react";
import { Bsvhu } from "@td/codegen-ui";
import { BsvhuWasteSummary } from "./BsvhuWasteSummary";
import { BsvhuJourneySummary } from "./BsvhuJourneySummary";
import { BsvhuJourneySummary } from "../../../../../Apps/Dashboard/Validation/Bsvhu/BsvhuJourneySummary";

interface Props {
bsvhu: Bsvhu;
Expand Down
Loading