Skip to content
Merged
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 @@ -10,6 +10,7 @@ import { getCandidature } from '@/app/_helpers';
import { ProjetBannerTemplate } from '@/components/molecules/projet/ProjetBanner.template';
import { StatutCandidatureBadge } from '@/components/molecules/candidature/StatutCandidatureBadge';
import { NotificationBadge } from '@/components/molecules/candidature/NotificationBadge';
import { PageWithErrorHandling } from '@/utils/PageWithErrorHandling';

type LayoutProps = {
children: React.ReactNode;
Expand Down Expand Up @@ -40,29 +41,31 @@ export default async function CandidatureLayout({
children,
params: { identifiant },
}: LayoutProps) {
const identifiantProjetValue = decodeParameter(identifiant);
const { identifiantProjet, notification, dépôt, instruction } =
await getCandidature(identifiantProjetValue);
return PageWithErrorHandling(async () => {
const identifiantProjetValue = decodeParameter(identifiant);
const { identifiantProjet, notification, dépôt, instruction } =
await getCandidature(identifiantProjetValue);

return (
<PageTemplate
banner={
<ProjetBannerTemplate
identifiantProjet={identifiantProjet}
href={notification ? Routes.Projet.details(identifiantProjet.formatter()) : undefined}
nom={dépôt.nomProjet}
localité={dépôt.localité}
badge={
<div className="flex gap-2">
<StatutCandidatureBadge statut={instruction.statut.statut} />
<NotificationBadge estNotifié={!!notification} />
</div>
}
dateDésignation={notification ? notification.notifiéeLe.formatter() : Option.none}
/>
}
>
{children}
</PageTemplate>
);
return (
<PageTemplate
banner={
<ProjetBannerTemplate
identifiantProjet={identifiantProjet}
href={notification ? Routes.Projet.details(identifiantProjet.formatter()) : undefined}
nom={dépôt.nomProjet}
localité={dépôt.localité}
badge={
<div className="flex gap-2">
<StatutCandidatureBadge statut={instruction.statut.statut} />
<NotificationBadge estNotifié={!!notification} />
</div>
}
dateDésignation={notification ? notification.notifiéeLe.formatter() : Option.none}
/>
}
>
{children}
</PageTemplate>
);
});
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import { Metadata, ResolvingMetadata } from 'next';
import { notFound } from 'next/navigation';

import { IdentifiantProjet } from '@potentiel-domain/projet';
import { mapToPlainObject } from '@potentiel-domain/core';

import { ProjetÉliminéBanner } from '@/components/molecules/projet/éliminé/ProjetÉliminéBanner';
import { PageTemplate } from '@/components/templates/Page.template';
import { decodeParameter } from '@/utils/decodeParameter';
import { IdentifiantParameter } from '@/utils/identifiantParameter';
import { getÉliminé } from '@/app/_helpers/getÉliminé';
import { PageWithErrorHandling } from '@/utils/PageWithErrorHandling';
import { getLauréatInfos } from '@/app/laureats/[identifiant]/_helpers';
import { ProjetLauréatBanner } from '@/components/molecules/projet/lauréat/ProjetLauréatBanner';

type LayoutProps = IdentifiantParameter & {
children: React.ReactNode;
Expand Down Expand Up @@ -34,11 +40,34 @@ export async function generateMetadata(
}
}

export default function ÉliminéLayout({ children, params: { identifiant } }: LayoutProps) {
const identifiantProjet = decodeParameter(identifiant);
return (
<PageTemplate banner={<ProjetÉliminéBanner identifiantProjet={identifiantProjet} />}>
{children}
</PageTemplate>
);
export default async function ÉliminéLayout({ children, params: { identifiant } }: LayoutProps) {
return PageWithErrorHandling(async () => {
const identifiantProjet = decodeParameter(identifiant);
const éliminé = await getÉliminé(identifiantProjet);

// dans le cas d'un recours accordé, le projet devient lauréat
if (!éliminé) {
const lauréat = await getLauréatInfos(
IdentifiantProjet.convertirEnValueType(identifiantProjet).formatter(),
);
return (
<ProjetLauréatBanner
identifiantProjet={identifiantProjet}
projet={mapToPlainObject(lauréat)}
/>
);
}
return (
<PageTemplate
banner={
<ProjetÉliminéBanner
identifiantProjet={identifiantProjet}
projet={mapToPlainObject(éliminé)}
/>
}
>
{children}
</PageTemplate>
);
});
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { Metadata, ResolvingMetadata } from 'next';

import { IdentifiantProjet } from '@potentiel-domain/projet';
import { mapToPlainObject } from '@potentiel-domain/core';

import { ProjetLauréatBanner } from '@/components/molecules/projet/lauréat/ProjetLauréatBanner';
import { PageTemplate } from '@/components/templates/Page.template';
import { decodeParameter } from '@/utils/decodeParameter';
import { IdentifiantParameter } from '@/utils/identifiantParameter';
import { PageWithErrorHandling } from '@/utils/PageWithErrorHandling';

import { getLauréatInfos } from './_helpers/getLauréat';

Expand Down Expand Up @@ -37,10 +39,22 @@ export async function generateMetadata(
}

export default function LauréatLayout({ children, params: { identifiant } }: LayoutProps) {
const identifiantProjet = decodeParameter(identifiant);
return (
<PageTemplate banner={<ProjetLauréatBanner identifiantProjet={identifiantProjet} />}>
{children}
</PageTemplate>
);
return PageWithErrorHandling(async () => {
const identifiantProjet = decodeParameter(identifiant);
const projet = await getLauréatInfos(
IdentifiantProjet.convertirEnValueType(identifiantProjet).formatter(),
);
return (
<PageTemplate
banner={
<ProjetLauréatBanner
identifiantProjet={identifiantProjet}
projet={mapToPlainObject(projet)}
/>
}
>
{children}
</PageTemplate>
);
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const ProjetBannerTemplate: FC<ProjetBannerProps> = ({
) : (
<p className="text-xl font-bold !text-theme-white mr-2">{nom}</p>
)}
<div className="hidden print:block">{badge}</div>
<div>{badge}</div>
{process.env.APPLICATION_STAGE !== 'production' && (
<CopyButton
textToCopy={identifiantProjet.formatter()}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
'use server';

import { FC } from 'react';

import { Routes } from '@potentiel-applications/routes';
import { IdentifiantProjet } from '@potentiel-domain/projet';
import { IdentifiantProjet, Lauréat } from '@potentiel-domain/projet';
import { Option } from '@potentiel-libraries/monads';
import { PlainType } from '@potentiel-domain/core';

import { withUtilisateur } from '@/utils/withUtilisateur';
import { getLauréatInfos } from '@/app/laureats/[identifiant]/_helpers/getLauréat';

import { ProjetBannerTemplate } from '../ProjetBanner.template';

Expand All @@ -16,25 +14,23 @@ import { StatutLauréatBadge } from './StatutLauréatBadge';
export type ProjetLauréatBannerProps = {
identifiantProjet: string;
noLink?: true;
projet: PlainType<Lauréat.ConsulterLauréatReadModel>;
};

export const ProjetLauréatBanner: FC<ProjetLauréatBannerProps> = async ({
export const ProjetLauréatBanner: FC<ProjetLauréatBannerProps> = ({
identifiantProjet,
noLink,
projet,
}) =>
withUtilisateur(async ({ rôle }) => {
const projet = await getLauréatInfos(
IdentifiantProjet.convertirEnValueType(identifiantProjet).formatter(),
);

const { nomProjet, localité, notifiéLe, statut } = projet;

return (
<ProjetBannerTemplate
badge={<StatutLauréatBadge statut={statut.statut} />}
localité={localité}
dateDésignation={Option.match(notifiéLe)
.some((date) => date.formatter())
.some((date) => date.date)
.none()}
/***
* @todo changer le check du rôle quand la page projet sera matérialisée dans le SSR (utiliser rôle.aLaPermissionDe)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,44 +1,36 @@
'use server';

import { FC } from 'react';

import { Routes } from '@potentiel-applications/routes';
import { IdentifiantProjet } from '@potentiel-domain/projet';
import { IdentifiantProjet, Éliminé } from '@potentiel-domain/projet';
import { Option } from '@potentiel-libraries/monads';
import { PlainType } from '@potentiel-domain/core';

import { withUtilisateur } from '@/utils/withUtilisateur';
import { getÉliminé } from '@/app/_helpers/getÉliminé';

import { ProjetBannerTemplate } from '../ProjetBanner.template';
import { ProjetLauréatBanner } from '../lauréat/ProjetLauréatBanner';

import { StatutÉliminéBadge } from './StatutÉliminéBadge';

export type ProjetÉliminéBannerProps = {
identifiantProjet: string;
noLink?: true;
projet: PlainType<Éliminé.ConsulterÉliminéReadModel>;
};

export const ProjetÉliminéBanner: FC<ProjetÉliminéBannerProps> = async ({
export const ProjetÉliminéBanner: FC<ProjetÉliminéBannerProps> = ({
identifiantProjet,
noLink,
projet,
}) =>
withUtilisateur(async ({ rôle }) => {
const projet = await getÉliminé(identifiantProjet);

// dans le cas d'un recours accordé, le projet devient lauréat
if (!projet) {
return <ProjetLauréatBanner identifiantProjet={identifiantProjet} />;
}

const { nomProjet, localité, notifiéLe } = projet;

return (
<ProjetBannerTemplate
badge={<StatutÉliminéBadge />}
localité={localité}
dateDésignation={Option.match(notifiéLe)
.some((date) => date.formatter())
.some((date) => date.date)
.none()}
/***
* @todo changer le check du rôle quand la page projet sera matérialisée dans le SSR (utiliser rôle.aLaPermissionDe)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const InviterPorteurForm: FC<InviterPorteurFormProps> = ({
return (
<>
{peutInviter && (
<Button iconId="fr-icon-user-line" className="w-full" onClick={() => setIsOpen(true)}>
<Button iconId="fr-icon-user-line" onClick={() => setIsOpen(true)}>
Inviter un nouvel utilisateur
</Button>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const AccèsListPage: FC<AccèsListPageProps> = ({
)}
</Section>
</div>
<div className="flex flex-1 flex-col gap-4 items-center">
<div className="flex flex-1 flex-col gap-4">
<InviterPorteurForm
identifiantProjet={identifiantProjet}
nombreDeProjets={nombreDeProjets}
Expand All @@ -56,7 +56,6 @@ export const AccèsListPage: FC<AccèsListPageProps> = ({
<Button
iconId="fr-icon-mail-line"
priority="secondary"
className="w-full"
linkProps={{
href: `mailto:${accès.map((item) => item.identifiantUtilisateur).join(',')}`,
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ Fonctionnalité: Demander le changement de puissance d'un projet lauréat

Scénario: Demander le changement de puissance et de puissance de site, en modifiant ou non la puissance, d'un projet lauréat pour l'AO duquel puissance de site est un champs requis
Etant donné le projet lauréat "Du bouchon lyonnais" avec :
| appel d'offres | PPE2 - Petit PV Bâtiment |
| appel d'offres | PPE2 - Petit PV Bâtiment |
| puissance de site | 1 |
Et la dreal "Dreal du rhône" associée à la région du projet
Quand le porteur demande le changement de puissance pour le projet lauréat avec :
| puissance de site | 1.1 |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ Fonctionnalité: Enregistrer un changement de puissance d'un projet lauréat par

Scénario: Enregistrer un changement de puissance et de puissance de site, en modifiant ou non la puissance, d'un projet lauréat pour un projet dont l'AO requiert la puissance de site
Etant donné le projet lauréat "Du bouchon lyonnais" avec :
| appel d'offres | PPE2 - Petit PV Bâtiment |
| appel d'offres | PPE2 - Petit PV Bâtiment |
| puissance de site | 1 |
Et la dreal "Dreal du nord" associée à la région du projet
Quand le porteur enregistre un changement de puissance pour le projet lauréat avec :
| puissance de site | <Puissance de site> |
| ratio puissance | <Ratio> |
| puissance de site | 1.1 |
| ratio puissance | <Ratio> |
Alors la puissance du projet lauréat devrait être mise à jour
Et le changement enregistré de puissance devrait être consultable
Et un email a été envoyé à la dreal avec :
Expand All @@ -41,9 +42,9 @@ Fonctionnalité: Enregistrer un changement de puissance d'un projet lauréat par
| url | https://potentiel.beta.gouv.fr/projets/.* |

Exemples:
| Ratio | Puissance de site |
| 1 | 1 |
| 1.05 | 1 |
| Ratio |
| 1 |
| 1.05 |

Scénario: Impossible d'enregistrer un changement de puissance d'un projet lauréat avec une valeur identique
Quand le porteur enregistre un changement de puissance pour le projet lauréat avec :
Expand Down
Loading