Skip to content

Commit

Permalink
[tra-15398]Mettre au DSFR la modale de signature de l'émetteur
Browse files Browse the repository at this point in the history
  • Loading branch information
JulianaJM committed Nov 27, 2024
1 parent 8b9f4a5 commit 28925fc
Show file tree
Hide file tree
Showing 10 changed files with 244 additions and 181 deletions.
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"),
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

0 comments on commit 28925fc

Please sign in to comment.