From 6b779acb096ad47adc4f3e5fcbc53af38faa5048 Mon Sep 17 00:00:00 2001 From: jerem Date: Tue, 4 Feb 2025 16:25:51 +0100 Subject: [PATCH] =?UTF-8?q?feat(atlas):=20ajout=20du=20contexte=20Atlas=20?= =?UTF-8?q?et=20r=C3=A9cup=C3=A9ration=20des=20constantes=20sur=20le=20ser?= =?UTF-8?q?veur?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/pages/admin/dashboard.tsx | 2 +- .../main/header/years-modal-button.tsx | 61 ++++++++++--------- .../main/tabs/components/sub-list-genders.tsx | 46 +++++++------- .../main/tabs/components/sub-list-sectors.tsx | 56 +++++++++-------- .../main/tabs/components/sub-list.tsx | 28 +++++---- .../atlas/components/main/tabs/fields/all.tsx | 8 ++- .../atlas/components/main/tabs/fields/one.tsx | 5 +- .../atlas/components/main/tabs/genders.tsx | 7 ++- .../atlas/components/main/tabs/general.tsx | 16 +++-- .../components/main/tabs/search/index.tsx | 4 +- .../atlas/components/main/tabs/sectors.tsx | 7 ++- client/src/pages/atlas/context.tsx | 51 ++++++++++++++++ client/src/pages/atlas/routes.tsx | 45 +++++++------- client/src/pages/atlas/useAtlas.tsx | 10 +++ server/src/routes/admin/index.js | 15 +++++ 15 files changed, 238 insertions(+), 123 deletions(-) create mode 100644 client/src/pages/atlas/context.tsx create mode 100644 client/src/pages/atlas/useAtlas.tsx diff --git a/client/src/pages/admin/dashboard.tsx b/client/src/pages/admin/dashboard.tsx index 8b72ffd6..d91e6e04 100644 --- a/client/src/pages/admin/dashboard.tsx +++ b/client/src/pages/admin/dashboard.tsx @@ -171,7 +171,7 @@ export default function Dashboard() {
- + diff --git a/client/src/pages/atlas/components/main/header/years-modal-button.tsx b/client/src/pages/atlas/components/main/header/years-modal-button.tsx index a96af019..7acaa125 100644 --- a/client/src/pages/atlas/components/main/header/years-modal-button.tsx +++ b/client/src/pages/atlas/components/main/header/years-modal-button.tsx @@ -4,21 +4,26 @@ import { useQuery } from '@tanstack/react-query'; import { Button, Modal, ModalContent, ModalTitle } from '@dataesr/dsfr-plus'; import { getFiltersValues } from '../../../../../api/atlas.ts'; -import { DEFAULT_CURRENT_YEAR } from '../../../../../constants.tsx'; +// import { DEFAULT_CURRENT_YEAR } from '../../../../../constants.tsx'; +import { useAtlas } from '../../../useAtlas.tsx'; export default function YearsModalButton() { const [isOpen, setIsOpen] = useState(false); const [searchParams] = useSearchParams(); - const currentYear = searchParams.get('annee_universitaire') || DEFAULT_CURRENT_YEAR; - const geoId = searchParams.get('geo_id') || ''; + const { DEFAULT_CURRENT_YEAR } = useAtlas(); + console.log("DEFAULT_CURRENT_YEAR", DEFAULT_CURRENT_YEAR); + + const currentYear = + searchParams.get("annee_universitaire") || DEFAULT_CURRENT_YEAR; + const geoId = searchParams.get("geo_id") || ""; const { data: filtersValues, isLoading: isLoadingFiltersValues } = useQuery({ queryKey: ["atlas/get-filters-values", geoId], - queryFn: () => getFiltersValues(geoId) - }) + queryFn: () => getFiltersValues(geoId), + }); if (isLoadingFiltersValues) { - return
Chargement des filtres ...
+ return
Chargement des filtres ...
; } function YearsList() { @@ -33,29 +38,29 @@ export default function YearsModalButton() { id="select" name="select" onChange={(e) => { - searchParams.set('annee_universitaire', e.target.value); + searchParams.set("annee_universitaire", e.target.value); window.location.search = searchParams.toString(); }} > - { - filtersValues.annees_universitaires.all.map((value: string) => ( - - )) - } + {filtersValues.annees_universitaires.all.map((value: string) => ( + + ))} - ) + ); } return ( @@ -63,16 +68,14 @@ export default function YearsModalButton() { - setIsOpen(false)} size='lg'> - - Sélection d'une année universitaire - + setIsOpen(false)} size="lg"> + Sélection d'une année universitaire diff --git a/client/src/pages/atlas/components/main/tabs/components/sub-list-genders.tsx b/client/src/pages/atlas/components/main/tabs/components/sub-list-genders.tsx index 1dbabbc3..d87c0356 100644 --- a/client/src/pages/atlas/components/main/tabs/components/sub-list-genders.tsx +++ b/client/src/pages/atlas/components/main/tabs/components/sub-list-genders.tsx @@ -5,8 +5,9 @@ import { useQuery } from "@tanstack/react-query"; import Template from "../../../../../../components/template/index.tsx"; import { getNumberOfStudentsByGenderAndSublevel } from "../../../../../../api/index.ts"; -import { DEFAULT_CURRENT_YEAR } from "../../../../../../constants.tsx"; import { getSubLevel } from "../../../../utils/index.tsx"; +// import { DEFAULT_CURRENT_YEAR } from "../../../../../../constants.tsx"; +import { useAtlas } from "../../../../useAtlas.tsx"; const MAX_ELEMENTS = 6; @@ -14,7 +15,9 @@ export default function SubListGenders() { const [searchParams] = useSearchParams(); const navigate = useNavigate(); const geoId = searchParams.get("geo_id") || ""; - const currentYear = searchParams.get("annee_universitaire") || DEFAULT_CURRENT_YEAR; + const { DEFAULT_CURRENT_YEAR } = useAtlas(); + const currentYear = + searchParams.get("annee_universitaire") || DEFAULT_CURRENT_YEAR; const [max, setMax] = useState(MAX_ELEMENTS); const { data, isLoading } = useQuery({ @@ -32,11 +35,9 @@ export default function SubListGenders() { if (!data) { return null; } - - const maxValue: number = Math.max( - ...data.map((el) => el.effectif_total) - ); - + + const maxValue: number = Math.max(...data.map((el) => el.effectif_total)); + // return null; // // Special case "Saint-Martin" (geo_id = 978) // data.data.forEach(item => { @@ -50,7 +51,7 @@ export default function SubListGenders() {
- {getSubLevel({geoId})} + {getSubLevel({ geoId })}
@@ -59,17 +60,15 @@ export default function SubListGenders() {
    {data.slice(0, max).map((item) => { - const size_f = Math.round(item.effectif_feminin * 100 / maxValue); - const size_m = Math.round(item.effectif_masculin * 100 / maxValue); + const size_f = Math.round((item.effectif_feminin * 100) / maxValue); + const size_m = Math.round((item.effectif_masculin * 100) / maxValue); return (
  • {item.nom}
    - - {item.effectif_total.toLocaleString()} - + {item.effectif_total.toLocaleString()} {["R", "D", "A", "U", "P"].includes(geoId?.charAt(0)) && (
  • ); })} - { - data.length > MAX_ELEMENTS && ( + {data.length > MAX_ELEMENTS && ( - ) - } + )}
); diff --git a/client/src/pages/atlas/components/main/tabs/components/sub-list-sectors.tsx b/client/src/pages/atlas/components/main/tabs/components/sub-list-sectors.tsx index 416039e7..969d1bc0 100644 --- a/client/src/pages/atlas/components/main/tabs/components/sub-list-sectors.tsx +++ b/client/src/pages/atlas/components/main/tabs/components/sub-list-sectors.tsx @@ -5,8 +5,9 @@ import { useQuery } from "@tanstack/react-query"; import Template from "../../../../../../components/template/index.tsx"; import { getNumberOfStudentsBySectorAndSublevel } from "../../../../../../api/index.ts"; -import { DEFAULT_CURRENT_YEAR } from "../../../../../../constants.tsx"; import { getSubLevel } from "../../../../utils/index.tsx"; +// import { DEFAULT_CURRENT_YEAR } from "../../../../../../constants.tsx"; +import { useAtlas } from "../../../../useAtlas.tsx"; const MAX_ELEMENTS = 6; @@ -14,7 +15,9 @@ export default function SubListSectors() { const [searchParams] = useSearchParams(); const navigate = useNavigate(); const geoId = searchParams.get("geo_id") || ""; - const currentYear = searchParams.get("annee_universitaire") || DEFAULT_CURRENT_YEAR; + const { DEFAULT_CURRENT_YEAR } = useAtlas(); + const currentYear = + searchParams.get("annee_universitaire") || DEFAULT_CURRENT_YEAR; const [max, setMax] = useState(MAX_ELEMENTS); const { data, isLoading } = useQuery({ @@ -32,11 +35,9 @@ export default function SubListSectors() { if (!data) { return null; } - - const maxValue: number = Math.max( - ...data.map((el) => el.effectif_total) - ); - + + const maxValue: number = Math.max(...data.map((el) => el.effectif_total)); + // return null; // // Special case "Saint-Martin" (geo_id = 978) // data.data.forEach(item => { @@ -50,7 +51,7 @@ export default function SubListSectors() {
- {getSubLevel({geoId})} + {getSubLevel({ geoId })}
@@ -59,17 +60,19 @@ export default function SubListSectors() {
    {data.slice(0, max).map((item) => { - const size_public = Math.round(item.effectif_secteur_public * 100 / maxValue); - const size_prive = Math.round(item.effectif_secteur_prive * 100 / maxValue); + const size_public = Math.round( + (item.effectif_secteur_public * 100) / maxValue + ); + const size_prive = Math.round( + (item.effectif_secteur_prive * 100) / maxValue + ); return (
  • {item.nom}
    - - {item.effectif_total.toLocaleString()} - + {item.effectif_total.toLocaleString()} {["R", "D", "A", "U", "P"].includes(geoId?.charAt(0)) && (
  • ); })} - { - data.length > MAX_ELEMENTS && ( + {data.length > MAX_ELEMENTS && ( - ) - } + )}
); diff --git a/client/src/pages/atlas/components/main/tabs/components/sub-list.tsx b/client/src/pages/atlas/components/main/tabs/components/sub-list.tsx index 1da083f8..2594e890 100644 --- a/client/src/pages/atlas/components/main/tabs/components/sub-list.tsx +++ b/client/src/pages/atlas/components/main/tabs/components/sub-list.tsx @@ -5,8 +5,9 @@ import { useQuery } from "@tanstack/react-query"; import Template from "../../../../../../components/template/index.tsx"; import { getNumberOfStudentsHistoricByLevel } from "../../../../../../api/index.ts"; -import { DEFAULT_CURRENT_YEAR } from "../../../../../../constants.tsx"; import { getSubLevel } from "../../../../utils/index.tsx"; +// import { DEFAULT_CURRENT_YEAR } from "../../../../../../constants.tsx"; +import { useAtlas } from "../../../../useAtlas.tsx"; const MAX_ELEMENTS = 6; @@ -14,7 +15,10 @@ export default function SubList() { const [searchParams] = useSearchParams(); const navigate = useNavigate(); const geoId = searchParams.get("geo_id") || ""; - const currentYear = searchParams.get("annee_universitaire") || DEFAULT_CURRENT_YEAR; + + const { DEFAULT_CURRENT_YEAR } = useAtlas(); + const currentYear = + searchParams.get("annee_universitaire") || DEFAULT_CURRENT_YEAR; const [max, setMax] = useState(MAX_ELEMENTS); const { data: dataHistoric, isLoading: isLoadingHistoric } = useQuery({ @@ -41,9 +45,9 @@ export default function SubList() { ); // Special case "Saint-Martin" (geo_id = 978) - dataHistoric.data.forEach(item => { - if (item.geo_id === '978') { - item.geo_id = 'D978'; + dataHistoric.data.forEach((item) => { + if (item.geo_id === "978") { + item.geo_id = "D978"; } }); @@ -52,7 +56,7 @@ export default function SubList() {
- {getSubLevel({geoId})} + {getSubLevel({ geoId })}
@@ -108,17 +112,19 @@ export default function SubList() { ); })} - { - dataHistoric.data.length > MAX_ELEMENTS && ( + {dataHistoric.data.length > MAX_ELEMENTS && ( - ) - } + )} ); diff --git a/client/src/pages/atlas/components/main/tabs/fields/all.tsx b/client/src/pages/atlas/components/main/tabs/fields/all.tsx index 87e9c92f..bda169bb 100644 --- a/client/src/pages/atlas/components/main/tabs/fields/all.tsx +++ b/client/src/pages/atlas/components/main/tabs/fields/all.tsx @@ -10,11 +10,15 @@ import { import FilieresGendersChart from "../../../../charts/filieres-genders.tsx"; import FilieresList from "../../../../../../components/filieres-list/index.tsx"; -import { DEFAULT_CURRENT_YEAR } from "../../../../../../constants.tsx"; +import { useAtlas } from "../../../../useAtlas.tsx"; +// import { DEFAULT_CURRENT_YEAR } from "../../../../../../constants.tsx"; export default function AllFields() { + const { DEFAULT_CURRENT_YEAR } = useAtlas(); + const [searchParams] = useSearchParams(); - const currentYear = searchParams.get("annee_universitaire") || DEFAULT_CURRENT_YEAR; + const currentYear = + searchParams.get("annee_universitaire") || DEFAULT_CURRENT_YEAR; const params = [...searchParams] .map(([key, value]) => `${key}=${value}`) .join("&"); diff --git a/client/src/pages/atlas/components/main/tabs/fields/one.tsx b/client/src/pages/atlas/components/main/tabs/fields/one.tsx index 36a354b1..9f61f664 100644 --- a/client/src/pages/atlas/components/main/tabs/fields/one.tsx +++ b/client/src/pages/atlas/components/main/tabs/fields/one.tsx @@ -20,7 +20,6 @@ import { DataByYear, MapBubbleDataProps, } from "../../../../../../types/atlas.ts"; -import { DEFAULT_CURRENT_YEAR } from "../../../../../../constants.tsx"; import ColumnsChart from "../../../../charts/columns.tsx"; import { getNumberOfStudentsByYear, @@ -29,7 +28,11 @@ import { getNumberOfStudentsByFieldAndSublevel, } from "../../../../../../api/atlas.ts"; +// import { DEFAULT_CURRENT_YEAR } from "../../../../../../constants.tsx"; +import { useAtlas } from "../../../../useAtlas.tsx"; + export default function OneField() { + const { DEFAULT_CURRENT_YEAR } = useAtlas(); const { idFiliere } = useParams(); const [searchParams] = useSearchParams(); const navigate = useNavigate(); diff --git a/client/src/pages/atlas/components/main/tabs/genders.tsx b/client/src/pages/atlas/components/main/tabs/genders.tsx index dc0a2410..833dc167 100644 --- a/client/src/pages/atlas/components/main/tabs/genders.tsx +++ b/client/src/pages/atlas/components/main/tabs/genders.tsx @@ -22,14 +22,17 @@ import { import GenderHistoChart from "../../../charts/genders-histo.tsx"; import { DataByYear, SimilarData } from "../../../../../types/atlas.ts"; import StudentsCardWithTrend from "../../../../../components/cards/students-card-with-trend/index.tsx"; -import { DEFAULT_CURRENT_YEAR } from "../../../../../constants.tsx"; import SubListGenders from "./components/sub-list-genders.tsx"; +// import { DEFAULT_CURRENT_YEAR } from "../../../../../constants.tsx"; +import { useAtlas } from "../../../useAtlas.tsx"; export function Genders() { const [chartView, setChartView] = useState<"basic" | "percentage">("basic"); const [chartType, setChartType] = useState<"column" | "line">("column"); const [searchParams] = useSearchParams(); - const currentYear = searchParams.get("annee_universitaire") || DEFAULT_CURRENT_YEAR; + const { DEFAULT_CURRENT_YEAR } = useAtlas(); + const currentYear = + searchParams.get("annee_universitaire") || DEFAULT_CURRENT_YEAR; const geoId = searchParams.get("geo_id") || ""; const params = [...searchParams] .map(([key, value]) => `${key}=${value}`) diff --git a/client/src/pages/atlas/components/main/tabs/general.tsx b/client/src/pages/atlas/components/main/tabs/general.tsx index ca724825..0abd3243 100644 --- a/client/src/pages/atlas/components/main/tabs/general.tsx +++ b/client/src/pages/atlas/components/main/tabs/general.tsx @@ -29,16 +29,20 @@ import MapWithPolygonAndBubbles from "../../../charts/map-with-polygon-and-bubbl import MapSkeleton from "../../../charts/skeletons/map.tsx"; import ArrondissementsMap from "../../../charts/arrondissements-map/index.tsx"; +import { useAtlas } from "../../../useAtlas.tsx"; +// import { DEFAULT_CURRENT_YEAR } from "../../../../../constants.tsx"; + import "./styles.scss"; -import { DEFAULT_CURRENT_YEAR } from "../../../../../constants.tsx"; export function General() { const [searchParams] = useSearchParams(); const params = [...searchParams] .map(([key, value]) => `${key}=${value}`) .join("&"); - const currentYear = searchParams.get("annee_universitaire") || DEFAULT_CURRENT_YEAR; const geoId = searchParams.get("geo_id") || ""; + const { DEFAULT_CURRENT_YEAR } = useAtlas(); + const currentYear = + searchParams.get("annee_universitaire") || DEFAULT_CURRENT_YEAR; const { data, isLoading } = useQuery({ queryKey: ["atlas/number-of-students", params], @@ -124,8 +128,8 @@ export function General() { let polygon; switch (item.geo_id) { // Nouvelle-Calédonie - case "D988": - case "A40": + case "D988": + case "A40": mapbubbleData.push({ z: item.data.find((d) => d.annee_universitaire === currentYear) @@ -499,7 +503,9 @@ export function General() { } } - const nbStudents = dataByYear?.find((el: DataByYear) => el.annee_universitaire === currentYear)?.effectif_total || 0; + const nbStudents = + dataByYear?.find((el: DataByYear) => el.annee_universitaire === currentYear) + ?.effectif_total || 0; return ( diff --git a/client/src/pages/atlas/components/main/tabs/search/index.tsx b/client/src/pages/atlas/components/main/tabs/search/index.tsx index f7c8e05d..ffd057aa 100644 --- a/client/src/pages/atlas/components/main/tabs/search/index.tsx +++ b/client/src/pages/atlas/components/main/tabs/search/index.tsx @@ -21,8 +21,9 @@ import FavoritesList from "../../../favorites-list/index.js"; import { GetLevelBadgeFromItem } from "../../../../utils/badges.js"; import "./styles.scss"; -import { DEFAULT_CURRENT_YEAR } from "../../../../../../constants.js"; +// import { DEFAULT_CURRENT_YEAR } from "../../../../../../constants.js"; import { DataByYear } from "../../../../../../types/atlas.ts"; +import { useAtlas } from "../../../../useAtlas.tsx"; type SearchTypes = { geo_id: string; @@ -36,6 +37,7 @@ export function Search() { const navigate = useNavigate(); const params = new URLSearchParams(window.location.search); const datasupr = params.get("datasupr") === "true"; + const { DEFAULT_CURRENT_YEAR } = useAtlas(); const currentYear = searchParams.get("annee_universitaire") || DEFAULT_CURRENT_YEAR; diff --git a/client/src/pages/atlas/components/main/tabs/sectors.tsx b/client/src/pages/atlas/components/main/tabs/sectors.tsx index 563f7b2a..1c010f43 100644 --- a/client/src/pages/atlas/components/main/tabs/sectors.tsx +++ b/client/src/pages/atlas/components/main/tabs/sectors.tsx @@ -22,14 +22,17 @@ import { } from "../../../../../api/atlas.ts"; import { DataByYear, SimilarData } from "../../../../../types/atlas.ts"; import StudentsCardWithTrend from "../../../../../components/cards/students-card-with-trend/index.tsx"; -import { DEFAULT_CURRENT_YEAR } from "../../../../../constants.tsx"; import SubListSectors from "./components/sub-list-sectors.tsx"; +// import { DEFAULT_CURRENT_YEAR } from "../../../../../constants.tsx"; +import { useAtlas } from "../../../useAtlas.tsx"; export function Sectors() { const [chartView, setChartView] = useState<"basic" | "percentage">("basic"); const [chartType, setChartType] = useState<"column" | "line">("column"); const [searchParams] = useSearchParams(); - const currentYear = searchParams.get("annee_universitaire") || DEFAULT_CURRENT_YEAR; + const { DEFAULT_CURRENT_YEAR } = useAtlas(); + const currentYear = + searchParams.get("annee_universitaire") || DEFAULT_CURRENT_YEAR; const geoId = searchParams.get("geo_id") || ""; const params = [...searchParams] .map(([key, value]) => `${key}=${value}`) diff --git a/client/src/pages/atlas/context.tsx b/client/src/pages/atlas/context.tsx new file mode 100644 index 00000000..85b9cb5f --- /dev/null +++ b/client/src/pages/atlas/context.tsx @@ -0,0 +1,51 @@ +import { createContext, ReactNode, useEffect, useState } from "react"; +const { VITE_APP_SERVER_URL } = import.meta.env; + +interface AtlasContextType { + DEFAULT_CURRENT_YEAR: string; + DEFAULT_GEO_ID: string; + START_YEAR: string; + END_YEAR: string; +} + +export const AtlasContext = createContext( + undefined +); + +export function AtlasProvider({ children }: { children: ReactNode }) { + const [value, setValue] = useState(); + + const transformDataToObject = ( + data: Array<{ key: string; value: string }> + ): AtlasContextType => { + return data.reduce((acc, curr) => { + return { + ...acc, + [curr.key]: curr.value, + }; + }, {}) as AtlasContextType; + }; + + useEffect(() => { + const fetchAtlasData = async () => { + try { + const response = await fetch( + VITE_APP_SERVER_URL + "/admin/get-constants?dashboardId=atlas" + ); + + const data = await response.json(); + + const transformedData = transformDataToObject(data); + setValue(transformedData); + } catch (error) { + console.error("Error fetching atlas data:", error); + } + }; + + fetchAtlasData(); + }, []); + + return ( + {children} + ); +} diff --git a/client/src/pages/atlas/routes.tsx b/client/src/pages/atlas/routes.tsx index 592b90a0..11d7ad72 100644 --- a/client/src/pages/atlas/routes.tsx +++ b/client/src/pages/atlas/routes.tsx @@ -12,30 +12,33 @@ import Accessibility from "./components/static-pages/accessibility.tsx"; import LegalMentions from "./components/static-pages/legal-mentions.tsx"; import CookieManagement from "./components/static-pages/cookie-management.tsx"; import Contact from "./components/static-pages/contact.tsx"; +import { AtlasProvider } from "./context.tsx"; export default function AtlasRoutes() { return ( - - }> - }> - } /> - } - /> - } /> - } /> - } - /> + + + }> + }> + } /> + } + /> + } /> + } /> + } + /> + + } /> + } /> + } /> + } /> + } /> - } /> - } /> - } /> - } /> - } /> - - + + ); } diff --git a/client/src/pages/atlas/useAtlas.tsx b/client/src/pages/atlas/useAtlas.tsx new file mode 100644 index 00000000..7b42c2a9 --- /dev/null +++ b/client/src/pages/atlas/useAtlas.tsx @@ -0,0 +1,10 @@ +import { useContext } from "react"; +import { AtlasContext } from "./context"; + +export function useAtlas() { + const context = useContext(AtlasContext); + if (context === undefined) { + throw new Error("useAtlas must be used within an AtlasProvider"); + } + return context; +} diff --git a/server/src/routes/admin/index.js b/server/src/routes/admin/index.js index 72e2fec0..2aeb3176 100644 --- a/server/src/routes/admin/index.js +++ b/server/src/routes/admin/index.js @@ -268,4 +268,19 @@ await run({dependentCollectionId}).catch(console.dir); }); +// get constants from a dashboard +router.route("/admin/get-constants").get(async (req, res) => { + const dashboardId = req.query.dashboardId; + if (!dashboardId) { + return res.status(400).json({ error: "Dashboard ID is required" }); + } + + const board = await db.collection("boards").findOne({ id: dashboardId }); + if (!board) { + return res.status(404).json({ error: "No document found" }); + } + + res.json(board.constants); +}); + export default router;
Constantes applicatives du serveurConstantes applicatives
Clé