Skip to content

Commit

Permalink
update prisma model (#67)
Browse files Browse the repository at this point in the history
* update prisma model

* Clean amendements stats

* fix naming

* AJout le filtrage par departement

* update

* fixes stats
  • Loading branch information
alexfauquette authored Feb 17, 2025
1 parent e7a3b09 commit e36ade1
Show file tree
Hide file tree
Showing 22 changed files with 1,044 additions and 298 deletions.
39 changes: 19 additions & 20 deletions app/[legislature]/dossier/[id]/AdditionalInfoCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ async function getDocumentsUnCached(ids: string[]) {
where: { uid: { in: ids } },
include: {
_count: {
// TODO: Check with HEnry if the naming `amendements` make sens for amendements
select: { amendementsCommission: true, amendements: true },
select: { amendements: true },
},
coSignataires: {
include: { acteurRef: { include: { groupeParlementaire: true } } },
Expand All @@ -45,8 +44,7 @@ export const AdditionalInfoCard = async (props: {
const data = await getDocuments(props.documentIds);

const documentsWithAmendements = data.filter(
(document) =>
document._count.amendements + document._count.amendementsCommission > 0
(document) => document._count.amendements
);
return (
<Accordion elevation={0} disableGutters defaultExpanded color="secondary">
Expand All @@ -67,22 +65,23 @@ export const AdditionalInfoCard = async (props: {
<InfoIcon sx={{ fontSize: "14px" }} />
</Stack>
<Stack direction="column" spacing={1}>
{documentsWithAmendements.map(({ uid, titrePrincipalCourt, _count }) => (
<div key={uid}>
<Typography variant="body2" fontWeight="bold">
{_count.amendementsCommission + _count.amendements}{" "}
amendements
</Typography>
<MuiLink
variant="body2"
fontWeight="light"
component={Link}
href={`/${props.legislature}/dossier/${props.dossierUid}/amendement?document=${uid}`}
>
{titrePrincipalCourt}
</MuiLink>
</div>
))}
{documentsWithAmendements.map(
({ uid, titrePrincipalCourt, _count }) => (
<div key={uid}>
<Typography variant="body2" fontWeight="bold">
{_count.amendements} amendements
</Typography>
<MuiLink
variant="body2"
fontWeight="light"
component={Link}
href={`/${props.legislature}/dossier/${props.dossierUid}/amendement?document=${uid}`}
>
{titrePrincipalCourt}
</MuiLink>
</div>
)
)}
</Stack>
</React.Fragment>
)}
Expand Down
2 changes: 1 addition & 1 deletion app/depute/[slug]/WeeklyActivity/WeeklyActivitySection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default function WeeklyActivitySection(props: {
<MenuItem value="commission">Commissions</MenuItem>
</Select>
</Stack>
<WeeklyActivityChart {...props} activityType={activityType} />;
<WeeklyActivityChart {...props} activityType={activityType} />
</div>
);
}
16 changes: 12 additions & 4 deletions app/depute/[slug]/amendements/AmendementsStatistics.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from "react";
import { prisma } from "@/prisma";
import Box from "@mui/material/Box";

async function getDeputeAmendementStatsUnCached(uid: string) {
try {
Expand Down Expand Up @@ -81,23 +82,30 @@ export async function AmendementsStatistics({
{}
);
return (
<table>
<Box
component="table"
sx={{
"td:nth-of-type(1)": { textAlign: "right" },
"td:nth-of-type(2)": { textAlign: "center" },
"td:nth-of-type(3)": { textAlign: "left" },
}}
>
<thead>
<tr>
<td>Etat</td>
<td>proposés</td>
<td />
<td>signés</td>
</tr>
</thead>
<tbody>
{[...sorts, ...etats].map((state) => (
<tr key={state}>
<td>{state}</td>
<td>{nbPropose[state] ?? 0}</td>
<td>{state}</td>
<td>{nbCoSigne[state] ?? 0}</td>
</tr>
))}
</tbody>
</table>
</Box>
);
}
2 changes: 1 addition & 1 deletion app/depute/[slug]/amendements/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export default async function Amendements({

return (
<Stack>
<p>Amendements</p>
<h2>Amendements</h2>

<AmendementsStatistics deputeUid={uid} />

Expand Down
32 changes: 20 additions & 12 deletions app/depute/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ async function getDeputeStatsUnCached(slug: string) {
nombreAmendements: true,
nombreInterventions: true,
nombreQuestions: true,
nombreDocumentsPublies: true,
statistiquesHebdomadaire: true,
},
});
Expand Down Expand Up @@ -68,17 +69,22 @@ const getStatsOnWeeklyActivity = React.cache(getStatsOnWeeklyActivityUnCached);

const baselineTypeToDeputeKey: Record<
string,
"nombreAmendements" | "nombreInterventions" | "nombreQuestions"
| "nombreAmendements"
| "nombreInterventions"
| "nombreQuestions"
| "nombreDocumentsPublies"
> = {
questions: "nombreQuestions",
interventions: "nombreInterventions",
amendements: "nombreAmendements",
"ACTEUR-QUESTIONS": "nombreQuestions",
"ACTEUR-INTERVENTIONS": "nombreInterventions",
"ACTEUR-AMENDEMENTS": "nombreAmendements",
"ACTEUR-DOCUMENTS": "nombreDocumentsPublies",
};

const baselineTypeToTitle: Record<string, string> = {
questions: "Nombre de questions",
interventions: "Nombre d'interventions",
amendements: "Nombre d'amendements",
nombreQuestions: "Nombre de questions",
nombreInterventions: "Nombre d'interventions",
nombreAmendements: "Nombre d'amendements",
nombreDocumentsPublies: "Nombre de documents publié",
};

const quantilesSentences = [
Expand Down Expand Up @@ -107,16 +113,18 @@ export default async function Page({ params }: { params: { slug: string } }) {
/>

{baselineStats.map(({ q20, q40, q60, q80, maximum, type, id }) => {
if (!baselineTypeToDeputeKey[type as string] || !deputeStats) {
if (type !== "ACTEUR" || !id.startsWith("17-AN-ACTEUR-")) {
// Stats pour les commission ou groupe parlementaire
// Ou pour le senat ou une autre legislature
return null;
}
const deputeKey = baselineTypeToDeputeKey[id.slice("17-AN-".length)];

if (!id.includes("-AN-")) {
// Enleve les stats liées au senat
if (!deputeKey || !deputeStats) {
return null;
}

const value = deputeStats[baselineTypeToDeputeKey[type]];
const value = deputeStats[deputeKey];

const quantiles = [q20, q40, q60, q80, maximum];

Expand All @@ -132,7 +140,7 @@ export default async function Page({ params }: { params: { slug: string } }) {
{value}
</Typography>
<Typography variant="body1" sx={{ textAlign: "right" }}>
{baselineTypeToTitle[type]}
{baselineTypeToTitle[deputeKey]}
</Typography>
<Box
sx={{
Expand Down
47 changes: 47 additions & 0 deletions app/deputes/DeputesFilter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
"use client";
import * as React from "react";

import Stack from "@mui/material/Stack";

import DeputesView from "./DeputesView";

import { FilterContainer } from "@/components/FilterContainer";
import { Filter } from "./Filter";
import { groupDeputes } from "./groupDeputes";
import { getDeputes } from "./getDeputes";

interface DeputeFilterProps extends ReturnType<typeof groupDeputes> {
deputes: Awaited<ReturnType<typeof getDeputes>>;
}

export default function DeputesFilter(props: DeputeFilterProps) {
const { deputes, indexesPerNom, indexesPerGroup, indexesPerCirco, groups } =
props;

const [numeroDepartement, setNumeroDepartement] = React.useState<
string | null
>(null);

return (
<React.Fragment>
<Stack spacing={3} useFlexGap flex={2}>
<FilterContainer>
<Filter
numeroDepartement={numeroDepartement}
handleNumeroDepartement={setNumeroDepartement}
/>
</FilterContainer>
</Stack>
<Stack spacing={3} flex={5}>
<DeputesView
deputes={deputes}
indexesPerNom={indexesPerNom}
indexesPerGroup={indexesPerGroup}
indexesPerCirco={indexesPerCirco}
groups={groups}
numeroDepartement={numeroDepartement}
/>
</Stack>
</React.Fragment>
);
}
24 changes: 17 additions & 7 deletions app/deputes/DeputesView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,11 @@ export default function DeputesView({
indexesPerGroup,
indexesPerNom,
groups,
}: { deputes: Awaited<ReturnType<typeof getDeputes>> } & ReturnType<
typeof groupDeputes
>) {
numeroDepartement,
}: {
deputes: Awaited<ReturnType<typeof getDeputes>>;
numeroDepartement: string | null;
} & ReturnType<typeof groupDeputes>) {
const [grouping, setGrouping] = React.useState<
"groupPolitique" | "alphabetique"
>("groupPolitique");
Expand All @@ -167,6 +169,7 @@ export default function DeputesView({
!depute.mandatPrincipal || depute.mandatPrincipal.dateFin !== null
).length;

const filterIsActive = !!search || numeroDepartement !== null;
return (
<Stack direction="column">
<Typography variant="h3" component="h1" fontWeight="bold">
Expand Down Expand Up @@ -205,12 +208,19 @@ export default function DeputesView({
.map((i) => deputes[i])
.filter(({ nom, prenom, mandatPrincipal }) => {
return (
!search ||
`${nom} ${prenom} ${mandatPrincipal?.departement ?? ""}`
.toLowerCase()
.includes(search.toLowerCase())
(!search ||
`${nom} ${prenom} ${mandatPrincipal?.departement ?? ""}`
.toLowerCase()
.includes(search.toLowerCase())) &&
(numeroDepartement === null ||
mandatPrincipal?.numDepartement === numeroDepartement)
);
});

if (filteredDeputes.length === 0) {
return null;
}

return (
<Accordion key={key} disableGutters elevation={0}>
<AccordionHeader
Expand Down
46 changes: 46 additions & 0 deletions app/deputes/Filter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"use client";
import * as React from "react";
import { Autocomplete, MenuItem } from "@mui/material";
import TextField from "@mui/material/TextField";
import { departements } from "./structureCircos";

type FilterProps = {
numeroDepartement: string | null;
handleNumeroDepartement: (numeroDepartement: string | null) => void;
};

export const Filter = (props: FilterProps) => {
const { numeroDepartement, handleNumeroDepartement } = props;

const value = React.useMemo(
() =>
numeroDepartement === null
? null
: departements.find((v) => v.numeroDepartement === numeroDepartement) ??
null,
[numeroDepartement]
);

return (
<div>
<Autocomplete
disablePortal
options={departements}
isOptionEqualToValue={(option, value) =>
option.numeroDepartement === value.numeroDepartement
}
value={value}
onChange={(_, newValue) =>
handleNumeroDepartement(newValue?.numeroDepartement ?? null)
}
groupBy={(option) => option.region}
getOptionLabel={(option) =>
`${option.nomDepartement} (${option.numeroDepartement})`
}
getOptionKey={(option) => option.numeroDepartement}

renderInput={(params) => <TextField {...params} label="Département" />}
/>
</div>
);
};
24 changes: 10 additions & 14 deletions app/deputes/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import Stack from "@mui/material/Stack";
import { groupDeputes } from "./groupDeputes";
import DeputesView from "./DeputesView";
import { getDeputes } from "./getDeputes";
import { FilterContainer } from "@/components/FilterContainer";
import { Filter } from "./Filter";
import DeputesFilter from "./DeputesFilter";

export default async function DeputesList() {
const deputes = await getDeputes("17");
Expand All @@ -25,20 +28,13 @@ export default async function DeputesList() {
gap: 5,
}}
>
{/* <Stack spacing={3} useFlexGap flex={2}>
<FilterContainer>
//<Filter theme={searchParams.theme ?? ""} />
</FilterContainer>
</Stack> */}
<Stack spacing={3} flex={5}>
<DeputesView
deputes={deputes}
indexesPerNom={indexesPerNom}
indexesPerGroup={indexesPerGroup}
indexesPerCirco={indexesPerCirco}
groups={groups}
/>
</Stack>
<DeputesFilter
deputes={deputes}
indexesPerNom={indexesPerNom}
indexesPerGroup={indexesPerGroup}
indexesPerCirco={indexesPerCirco}
groups={groups}
/>
</Container>
);
}
Loading

0 comments on commit e36ade1

Please sign in to comment.