Skip to content

Commit

Permalink
feat(admin,api): add on-site page for AAP settings v3 and refactor ov…
Browse files Browse the repository at this point in the history
…erall

- Implemented the on-site page for AAP settings v3, allowing users to manage on-site agency information.
- Refactored various components and hooks to improve code readability and maintainability.
  • Loading branch information
ThomasDos committed Sep 4, 2024
1 parent 1a4671f commit 1bbf320
Show file tree
Hide file tree
Showing 13 changed files with 699 additions and 263 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,57 @@
import { EnhancedSectionCard } from "@/components/card/enhanced-section-card/EnhancedSectionCard";
import { Organism } from "@/graphql/generated/graphql";
import Accordion from "@codegouvfr/react-dsfr/Accordion";
import Badge from "@codegouvfr/react-dsfr/Badge";
import Button from "@codegouvfr/react-dsfr/Button";
import { useRouter } from "next/navigation";

const VisibilityBadge = ({ isVisible }: { isVisible: boolean }) => {
return (
<Badge severity={isVisible ? "success" : "error"}>
{isVisible ? "Visible" : "Invisible"}
</Badge>
<div className="flex items-center">
<Badge severity={isVisible ? "success" : "error"} small>
{isVisible ? "Visible" : "Invisible"}
</Badge>
</div>
);
};

const OrganismRow = ({
organism,
index,
}: {
organism: {
id: string;
label: string;
isVisibleInCandidateSearchResults: boolean;
informationsCommerciales?: {
nom?: string | null;
} | null;
};
index: number;
}) => {
const router = useRouter();
return (
<div
className={`flex py-3 w-full justify-between border-b border-b-neutral-200 ${
!index && "border-t border-t-neutral-200"
}`}
>
<div className="flex items-center gap-2">
<p className="mb-0 ">
{organism.informationsCommerciales?.nom || organism.label}
</p>
<VisibilityBadge
isVisible={!!organism.isVisibleInCandidateSearchResults}
/>
</div>

<Button
priority="tertiary no outline"
onClick={() =>
router.push(`/agencies-settings-v3/organisms/${organism.id}/on-site`)
}
>
Modifier
</Button>
</div>
);
};

Expand Down Expand Up @@ -43,25 +87,9 @@ export const AgenciesSettingsSectionOnSite = ({
candidats.
</p>
)}
<div className="fr-accordions-group sm:pl-10">
{organisms.map((o) => (
<Accordion
key={o.id}
label={
<div className="flex items-center gap-2">
<span className="min-w-48">
{o.informationsCommerciales?.nom || o.label}
</span>
<VisibilityBadge
isVisible={o.isVisibleInCandidateSearchResults}
/>
</div>
}
>
<p>
{o.isVisibleInCandidateSearchResults ? "Visible" : "Invisible"}
</p>
</Accordion>
<div className="sm:pl-10 flex flex-col">
{organisms.map((organism, index) => (
<OrganismRow key={organism.id} organism={organism} index={index} />
))}
</div>
</EnhancedSectionCard>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { useGraphQlClient } from "@/components/graphql/graphql-client/GraphqlClient";
import { graphql } from "@/graphql/generated";
import { useQuery } from "@tanstack/react-query";
import { useParams } from "next/navigation";

const getOrganismQuery = graphql(`
query getOrganismForOrganismOnSitePage($organismId: ID!) {
organism_getOrganism(id: $organismId) {
id
label
informationsCommerciales {
id
nom
telephone
siteInternet
emailContact
}
remoteZones
managedDegrees {
id
degree {
id
label
}
}
domaines {
id
label
}
conventionCollectives {
id
label
}
}
}
`);

export const useOnSiteOrganism = () => {
const { organismId } = useParams<{ organismId: string }>();
const { graphqlClient } = useGraphQlClient();

const { data: getOrganismResponse } = useQuery({
queryKey: [organismId, "organism"],
queryFn: () => graphqlClient.request(getOrganismQuery, { organismId }),
enabled: !!organismId,
});

const organism = getOrganismResponse?.organism_getOrganism;

const organismName =
organism?.informationsCommerciales?.nom || organism?.label;

return { organism, organismId, organismName };
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"use client";
import { FormOptionalFieldsDisclaimer } from "@/components/form-optional-fields-disclaimer/FormOptionalFieldsDisclaimer";
import { Breadcrumb } from "@codegouvfr/react-dsfr/Breadcrumb";
import DomainesCcnsDegreesForm from "../../_components/domaines-ccns-degrees-form/DomainesCcnsDegreesForm";
import { useOnSiteOrganism } from "../_components/onSiteOrganism.hook";

const DomainesCcnsDegreesOnSitePage = () => {
const { organismId, organismName } = useOnSiteOrganism();

return (
<div className="flex flex-col">
<Breadcrumb
currentPageLabel="Filières, branches et niveaux"
homeLinkProps={{
href: `/`,
}}
segments={[
{
label: "Paramètres",
linkProps: { href: "/agencies-settings-v3" },
},
{
label: organismName,
linkProps: {
href: `/agencies-settings-v3/organisms/${organismId}/on-site`,
},
},
]}
/>
<h1>Filières, branches et niveaux</h1>
<FormOptionalFieldsDisclaimer />
<p>
Sélectionnez toutes les filières, branches et niveaux gérés par votre
structure.
</p>
<DomainesCcnsDegreesForm
organismId={organismId}
backButtonUrl={`/agencies-settings-v3/organisms/${organismId}/on-site`}
/>
</div>
);
};

export default DomainesCcnsDegreesOnSitePage;
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { useGraphQlClient } from "@/components/graphql/graphql-client/GraphqlClient";
import { graphql } from "@/graphql/generated";
import { CreateOrUpdateInformationsCommercialesInput } from "@/graphql/generated/graphql";

import { useMutation, useQuery } from "@tanstack/react-query";
import { useParams } from "next/navigation";

const getOrganismQuery = graphql(`
query getOrganismForInformationOnSitePage($organismId: ID!) {
organism_getOrganism(id: $organismId) {
id
label
informationsCommerciales {
id
nom
telephone
siteInternet
emailContact
adresseNumeroEtNomDeRue
adresseInformationsComplementaires
adresseCodePostal
adresseVille
conformeNormesAccessbilite
}
}
}
`);

const createOrUpdateInformationsCommercialesMutation = graphql(`
mutation createOrUpdateInformationsCommercialesMutation(
$createOrUpdateInformationsCommercialesInput: CreateOrUpdateInformationsCommercialesInput!
) {
organism_createOrUpdateInformationsCommerciales(
informationsCommerciales: $createOrUpdateInformationsCommercialesInput
) {
id
}
}
`);

export const useOrganismInformationOnSite = () => {
const { graphqlClient } = useGraphQlClient();
const { organismId } = useParams<{ organismId: string }>();
const { data, isLoading } = useQuery({
queryKey: [organismId, "organism"],
queryFn: () =>
graphqlClient.request(getOrganismQuery, {
organismId,
}),
});

const { mutateAsync: createOrUpdateInformationsCommerciales } = useMutation({
mutationFn: (
informationsCommerciales: CreateOrUpdateInformationsCommercialesInput,
) =>
graphqlClient.request(createOrUpdateInformationsCommercialesMutation, {
createOrUpdateInformationsCommercialesInput: informationsCommerciales,
}),
});

const organism = data?.organism_getOrganism;
const informationsCommerciales = organism?.informationsCommerciales;

return {
organism,
isLoading,
organismId,
informationsCommerciales,
createOrUpdateInformationsCommerciales,
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
"use client";

import { ConformiteNormeAccessibilite } from "@/graphql/generated/graphql";
import Breadcrumb from "@codegouvfr/react-dsfr/Breadcrumb";
import OrganismInformationForm from "../../../_components/OrganismInformationForm";
import { OrganismInformationFormData } from "../../../_components/organismInformationFormSchema";
import { useOrganismInformationOnSite } from "./organismInformationOnSite.hook";

const InformationsOnSitePage = () => {
const {
organism,
informationsCommerciales,
organismId,
createOrUpdateInformationsCommerciales,
} = useOrganismInformationOnSite();
const handleSubmit = async (data: OrganismInformationFormData) => {
const input = {
organismId,
nom: data.nom,
telephone: data.telephone,
siteInternet: data.siteInternet,
emailContact: data.emailContact,
adresseNumeroEtNomDeRue: data.adresseNumeroEtNomDeRue,
adresseInformationsComplementaires:
data.adresseInformationsComplementaires,
adresseCodePostal: data.adresseCodePostal,
adresseVille: data.adresseVille,
conformeNormesAccessbilite:
data.conformeNormesAccessibilite as ConformiteNormeAccessibilite,
};

await createOrUpdateInformationsCommerciales(input);
};

const organismName =
organism?.informationsCommerciales?.nom || organism?.label;

if (!organism) {
return null;
}
const defaultData = {
adresseNumeroEtNomDeRue:
informationsCommerciales?.adresseNumeroEtNomDeRue ?? "",
adresseInformationsComplementaires:
informationsCommerciales?.adresseInformationsComplementaires ?? "",
adresseCodePostal: informationsCommerciales?.adresseCodePostal ?? "",
adresseVille: informationsCommerciales?.adresseVille ?? "",
nom: informationsCommerciales?.nom ?? "",
telephone: informationsCommerciales?.telephone ?? "",
siteInternet: informationsCommerciales?.siteInternet ?? "",
emailContact: informationsCommerciales?.emailContact ?? "",
conformeNormesAccessibilite:
informationsCommerciales?.conformeNormesAccessbilite as any,
};

return (
<div className="flex flex-col">
<Breadcrumb
currentPageLabel={"Informations affichées au candidat"}
homeLinkProps={{
href: `/`,
}}
segments={[
{
label: "Paramètres",
linkProps: { href: "/agencies-settings-v3" },
},
{
label: organismName,
linkProps: {
href: `/agencies-settings-v3/organisms/${organismId}/on-site`,
},
},
]}
/>
<OrganismInformationForm
mutationOnSubmit={handleSubmit}
pathRedirection={`/agencies-settings-v3/organisms/${organismId}/on-site`}
defaultData={defaultData}
/>
</div>
);
};

export default InformationsOnSitePage;
Loading

0 comments on commit 1bbf320

Please sign in to comment.