diff --git a/client/src/api/contribution-api/getAllDatas.tsx b/client/src/api/contribution-api/getAllDatas.tsx
new file mode 100644
index 0000000..49a7a74
--- /dev/null
+++ b/client/src/api/contribution-api/getAllDatas.tsx
@@ -0,0 +1,36 @@
+import { useQuery } from "@tanstack/react-query";
+import { postHeaders } from "../../config/api";
+
+const routes = [
+ "contacts",
+ "contribute",
+ "production",
+ "remove-user",
+ "update-user-data",
+];
+
+const fetchAllData = async (baseApiUrl) => {
+ const fetchPromises = routes.map(async (route) => {
+ const url = `${baseApiUrl}/${route}`;
+ const response = await fetch(url, {
+ headers: postHeaders,
+ });
+ if (!response.ok) {
+ throw new Error(`Failed to fetch from ${route}`);
+ }
+ return response.json();
+ });
+
+ return Promise.all(fetchPromises);
+};
+
+const ContributionAllDatas = (baseApiUrl) => {
+ const fetchContributions = () => fetchAllData(baseApiUrl);
+ const { data, isLoading, isError, refetch } = useQuery(
+ ["allContributions"],
+ fetchContributions
+ );
+ return { data, isLoading, isError, refetch };
+};
+
+export default ContributionAllDatas;
diff --git a/client/src/api/utils/buildURL.tsx b/client/src/api/utils/buildURL.tsx
index 33d0e12..81eae26 100644
--- a/client/src/api/utils/buildURL.tsx
+++ b/client/src/api/utils/buildURL.tsx
@@ -26,7 +26,7 @@ export const buildURL = (
const sorted = sort === "ASC" ? "sort=created_at" : "sort=-created_at";
const where: any = {};
- if (query.trim() !== "") {
+ if (typeof query === "string" && query.trim() !== "") {
const isObjectId = /^[0-9a-fA-F]{24}$/.test(query);
if (isObjectId) {
@@ -57,6 +57,7 @@ export const buildURL = (
return `${baseApiUrl}/${baseUrl}?${sorted}&page=${page}&max_results=${max_results}${whereQuery}${fromAppQuery}`;
};
+
export const buildStatsURL = (
filter: string,
sort: string = "ASC",
diff --git a/client/src/pages/contact-contributionbyobject-page/components/search-section.tsx b/client/src/pages/contact-contributionbyobject-page/components/search-section.tsx
index ce8eedb..103f580 100644
--- a/client/src/pages/contact-contributionbyobject-page/components/search-section.tsx
+++ b/client/src/pages/contact-contributionbyobject-page/components/search-section.tsx
@@ -11,12 +11,12 @@ const SearchSection: React.FC<{
onSearch={(value) => handleSearch(value || "")}
isLarge
buttonLabel="Rechercher"
- placeholder="Rechercher par nom ou ID"
+ placeholder="Rechercher par nom, ID ou mot clé"
/>
{query
- .filter((item) => item.trim() !== "")
- .map((item, index) => (
+ ?.filter((item) => item.trim() !== "")
+ ?.map((item, index) => (
+): string {
+ const basePathMap: { [key: string]: { [key: string]: string } | string } = {
+ contacts: {
+ scanr: "/scanr-contact",
+ paysage: "/paysage-contact",
+ bso: "/bso-contact",
+ curiexplore: "/curiexplore-contact",
+ "works-magnet": "/works-magnet-contact",
+ datasupr: "/datasupr-contact",
+ },
+ contribute_production: "/scanr-apioperations",
+ "remove-user": "/scanr-removeuser",
+ "update-user-data": "/scanr-namechange",
+ contribute: "/scanr-contributionPage",
+ };
+
+ let basePath = "";
+
+ if (productions?.length > 1) {
+ basePath = "/scanr-apioperations";
+ } else if (objectId) {
+ basePath = "/scanr-contributionPage";
+ } else if (fromApplication) {
+ basePath = "/scanr-contact";
+ } else {
+ basePath = (basePathMap[collectionName] as string) || "";
+ }
+
+ return id
+ ? `${basePath}?page=1&query=${id}&searchInMessage=false&sort=DESC&status=choose`
+ : basePath;
+}
diff --git a/client/src/pages/home/components/item.tsx b/client/src/pages/home/components/item.tsx
new file mode 100644
index 0000000..4843b91
--- /dev/null
+++ b/client/src/pages/home/components/item.tsx
@@ -0,0 +1,153 @@
+import { Badge, Col, Container, Link, Row, Text } from "@dataesr/dsfr-plus";
+import "./styles.scss";
+import { AllContributionsProps } from "../../../types";
+import { generateLinkFromAllDatas } from "./generate-links";
+import {
+ BadgeColor,
+ BadgeStatus,
+ StatusLabel,
+ typeIcon,
+ TypeLabel,
+} from "../../../utils";
+
+const AllContributions: React.FC = ({
+ data,
+ query,
+}) => {
+ const highlightQuery = (text: string, query: string) => {
+ if (!query) return text;
+
+ const escapedQuery = query.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
+ const regex = new RegExp(`(${escapedQuery})`, "gi");
+
+ return text?.replace(regex, '$1');
+ };
+
+ return (
+
+ {data.length === 0 ? (
+ Pas de résultat
+ ) : (
+ data?.map((email, index) => {
+ const link = generateLinkFromAllDatas(
+ email.collectionName,
+ email.fromApplication,
+ email.id,
+ email.objectId,
+ email.productions
+ );
+ const creationDate = new Date(email.created_at);
+ const formattedDate = creationDate.toLocaleDateString("fr-FR");
+ const formattedTime = creationDate.toLocaleTimeString("fr-FR", {
+ hour: "2-digit",
+ minute: "2-digit",
+ });
+
+ let badgeContent = "";
+ if (email.productions?.length > 1) {
+ badgeContent = "Lier des publications";
+ } else if (email.objectId && !email.productions) {
+ badgeContent = "Contribution par objet";
+ } else badgeContent = "Contact";
+
+ return (
+
+
+
+
+ {badgeContent && (
+
+ {badgeContent}
+
+ )}
+ {badgeContent === "Lier des publications" && (
+
+ scanR
+
+ )}
+ {email.fromApplication && (
+
+ {email.fromApplication}
+
+ )}
+
+ {StatusLabel({ status: email.status })}
+
+ {email?.objectType && (
+ <>
+
+ {TypeLabel({ type: email.objectType })}
+
+
+ scanR
+
+ >
+ )}
+ {email?.comment ||
+ (email?.team?.length > 0 && (
+
+ {`Traité par ${email.team[0]}`}
+
+ ))}
+
+
+
+ Contribution de{" "}
+
+ {email?.name} - {email?.email}
+
+
+
+
+ Date de la contribution : {formattedDate} à{" "}
+ {formattedTime}
+
+
+
+
+
+
+
+ );
+ })
+ )}
+
+ );
+};
+
+export default AllContributions;
diff --git a/client/src/pages/home/components/styles.scss b/client/src/pages/home/components/styles.scss
new file mode 100644
index 0000000..7397420
--- /dev/null
+++ b/client/src/pages/home/components/styles.scss
@@ -0,0 +1,40 @@
+.email-item {
+ padding: 1.5rem;
+ border-radius: 8px;
+ margin-top: 1rem;
+ border-bottom: 3px solid #f0f0f0;
+}
+
+.email-content {
+ word-wrap: break-word;
+ overflow-wrap: break-word;
+ word-break: break-all;
+}
+
+.copy-button {
+ border: none;
+ background: none;
+ cursor: pointer;
+}
+
+.copied-text {
+ color: #4caf50;
+ margin-right: 0.5rem;
+}
+
+@media (max-width: 768px) {
+ .email-item {
+ padding: 1rem;
+ }
+ .email-content {
+ font-size: 0.9rem;
+ }
+ .copy-icon {
+ display: inline-block;
+ margin-left: 0.5rem;
+ }
+}
+.highlight {
+ background-color: yellow;
+ font-weight: bold;
+}
diff --git a/client/src/pages/home/index.tsx b/client/src/pages/home/index.tsx
index a0b0a45..fce2410 100644
--- a/client/src/pages/home/index.tsx
+++ b/client/src/pages/home/index.tsx
@@ -1,135 +1,104 @@
-import { Container, Row, Title } from "@dataesr/dsfr-plus";
-// import ContributionsGraphByYear from "../../components/graphs/contributions-by-year";
-// import ContributionsGraphByName from "../../components/graphs/contributions-by-name";
-// import ContributionsGraphByStatus from "../../components/graphs/by-status";
-// import ContributionsGraphByTags from "../../components/graphs/by-tags";
-// import ContributionsGraphByDomains from "../../components/graphs/by-domains";
-// import ContributionsGraphByTypes from "../../components/graphs/by-types";
-// import AdminTreatmentGraph from "../../components/graphs/treatment-by-admin";
-// import AdminResponseGraph from "../../components/graphs/response-by-admin";
-// import ContributionsGraphByProductions from "../../components/graphs/by-missing-productions";
-// import CommentsGraphByTeamMember from "../../components/graphs/comment-by-team";
-// import ContributionsGraphByYearAndType from "../../components/graphs/contribution-by-type";
-// import { useState } from "react";
-// import { contactUrl, contributionUrl } from "../../config/api";
-// import ContributionData from "../../api/contribution-api/getData";
+import { Col, Container, Title } from "@dataesr/dsfr-plus";
+import SearchSection from "../contact-contributionbyobject-page/components/search-section";
+import { useState, useEffect } from "react";
+import ContributionAllDatas from "../../api/contribution-api/getAllDatas";
+import AllContributions from "./components/item";
+
+const isDevelopment = import.meta.env.VITE_HEADER_TAG === "Development";
+const prodUrl = import.meta.env.VITE_BASE_API_URL;
+
+const url = isDevelopment ? "http://localhost:3000/api" : `${prodUrl}/api`;
const Home = () => {
- // const [filter, setFilter] = useState("contributions");
- // const url = filter === "object" ? contributionUrl : contactUrl;
- // const { data, isLoading, isError } = ContributionData(url);
- // const contributions = data?.data as { data: [] };
+ const [query, setQuery] = useState([]);
+ const [highlightedQuery, setHighlightedQuery] = useState("");
+ const [filteredData, setFilteredData] = useState([]);
+ const { data, isLoading, isError } = ContributionAllDatas(url);
+
+ useEffect(() => {
+ if (data && data.length > 0) {
+ const allItems = data.flatMap((item) => item.data || []);
+ const combinedQuery = highlightedQuery || query.join(" ");
+
+ if (combinedQuery.trim() !== "") {
+ const filtered = allItems.filter((item) => {
+ return (
+ item.name?.toLowerCase().includes(combinedQuery.toLowerCase()) ||
+ item.email?.toLowerCase().includes(combinedQuery.toLowerCase()) ||
+ item.message?.toLowerCase().includes(combinedQuery.toLowerCase())
+ );
+ });
+
+ const sortedFiltered = filtered.sort((a, b) => {
+ return (
+ new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
+ );
+ });
+
+ setFilteredData(sortedFiltered);
+ } else {
+ const twentyFourHoursAgo = new Date();
+ twentyFourHoursAgo.setHours(twentyFourHoursAgo.getHours() - 24);
+
+ const recentContributions = allItems.filter((item) => {
+ const createdAt = new Date(item.created_at);
+ return createdAt >= twentyFourHoursAgo;
+ });
+
+ const sortedRecentContributions = recentContributions.sort((a, b) => {
+ return (
+ new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
+ );
+ });
+
+ setFilteredData(sortedRecentContributions);
+ }
+ }
+ }, [highlightedQuery, query, data]);
+
+ const handleSearch = (value: string) => {
+ const trimmedValue = value.trim();
+ if (trimmedValue !== "") {
+ setQuery((prev) => [...prev, trimmedValue]);
+ setHighlightedQuery(trimmedValue);
+ } else {
+ setQuery([]);
+ setHighlightedQuery("");
+ setFilteredData([]);
+ }
+ };
+
+ const handleRemoveQueryItem = (item: string) => {
+ setQuery(query.filter((q) => q !== item));
+ if (item === highlightedQuery) {
+ setHighlightedQuery("");
+ setFilteredData([]);
+ }
+ };
return (
Bienvenue sur le Guichet numérique du DISD
-
- {/*
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {url === contributionUrl && (
-
-
-
- )}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- */}
-
+
+
+ Sans filtre, voici plus bas les contributions sur les dernières 24h.
+
+
+
+ {filteredData.length > 0 ? (
+
+ ) : (
+ query.length > 0 && (
+ Aucun résultat correspondant à votre recherche.
+ )
+ )}
+
+ {isLoading && Loading...
}
+ {isError && Oops...
}
);
};
diff --git a/client/src/pages/last-mails-sent/components/styles.scss b/client/src/pages/last-mails-sent/components/styles.scss
index 941a5e8..0986bbc 100644
--- a/client/src/pages/last-mails-sent/components/styles.scss
+++ b/client/src/pages/last-mails-sent/components/styles.scss
@@ -1,8 +1,8 @@
.email-item {
- background-color: #f1f4f8;
padding: 1.5rem;
border-radius: 8px;
margin-top: 1rem;
+ border-bottom: 3px solid #f0f0f0;
}
.email-content {
diff --git a/client/src/types/index.ts b/client/src/types/index.ts
index 6af08c0..d8175f6 100644
--- a/client/src/types/index.ts
+++ b/client/src/types/index.ts
@@ -16,10 +16,21 @@ export interface Contribution {
modified_at?: string;
threads?: Thread[];
fromApplication: string;
+ emails?: any;
}
export interface LastMailsSentProps {
- data: { emails: Contribution[] };
+ data: {
+ length: number;
+ map(
+ arg0: (email: any, index: any) => import("react/jsx-runtime").JSX.Element
+ ): import("react").ReactNode;
+ emails: Contribution[];
+ };
+}
+
+export interface AllContributionsProps {
+ data: Contribution[];
}
export interface ContributorSummaryProps {
contributions: Contribution[];
diff --git a/server/routes/contacts/get/index.ts b/server/routes/contacts/get/index.ts
index 2360690..0665317 100644
--- a/server/routes/contacts/get/index.ts
+++ b/server/routes/contacts/get/index.ts
@@ -25,7 +25,7 @@ getContactRoutes.get(
filters.fromApplication = fromApplication;
}
- const limit = parseInt(max_results as string, 10) || 20;
+ const limit = parseInt(max_results as string, 10) || 2000;
const skip = (parseInt(page as string, 10) - 1) * limit;
const sortField = sort.startsWith("-") ? sort.substring(1) : sort;
const sortOrder = sort.startsWith("-") ? -1 : 1;
diff --git a/server/routes/contributionObjectRoutes/get/index.ts b/server/routes/contributionObjectRoutes/get/index.ts
index 8bac0ba..2ebc786 100644
--- a/server/routes/contributionObjectRoutes/get/index.ts
+++ b/server/routes/contributionObjectRoutes/get/index.ts
@@ -17,11 +17,11 @@ getContributionObjectRoutes.get(
where = "{}",
sort = "created_at",
page = 1,
- max_results = 20,
+ max_results = "",
} = query;
const filters = JSON.parse(where as string);
- const limit = parseInt(max_results as string, 10) || 20;
+ const limit = parseInt(max_results as string, 10) || 2000;
const skip = (parseInt(page as string, 10) - 1) * limit;
const sortField = sort.startsWith("-") ? sort.substring(1) : sort;
diff --git a/server/routes/productions/get/index.ts b/server/routes/productions/get/index.ts
index af91722..cdd5963 100644
--- a/server/routes/productions/get/index.ts
+++ b/server/routes/productions/get/index.ts
@@ -16,11 +16,11 @@ getProductionsRoutes.get(
where = "{}",
sort = "created_at",
page = 1,
- max_results = 20,
+ max_results = "",
} = query;
const filters = JSON.parse(where as string);
- const limit = parseInt(max_results as string, 10) || 20;
+ const limit = parseInt(max_results as string, 10) || 2000;
const skip = (parseInt(page as string, 10) - 1) * limit;
const sortField = sort.startsWith("-") ? sort.substring(1) : sort;
diff --git a/server/routes/remove-user/get/index.ts b/server/routes/remove-user/get/index.ts
index 72288e9..cdc1a7b 100644
--- a/server/routes/remove-user/get/index.ts
+++ b/server/routes/remove-user/get/index.ts
@@ -17,11 +17,11 @@ getRemoveUserRoutes.get(
where = "{}",
sort = "created_at",
page = 1,
- max_results = 20,
+ max_results = "",
} = query;
const filters = JSON.parse(where as string);
- const limit = parseInt(max_results as string, 10) || 20;
+ const limit = parseInt(max_results as string, 10) || 2000;
const skip = (parseInt(page as string, 10) - 1) * limit;
const sortField = sort.startsWith("-") ? sort.substring(1) : sort;
diff --git a/server/routes/update-user-data/get/index.ts b/server/routes/update-user-data/get/index.ts
index ab271a0..7c63e29 100644
--- a/server/routes/update-user-data/get/index.ts
+++ b/server/routes/update-user-data/get/index.ts
@@ -17,11 +17,11 @@ getUpdateUserDataRoutes.get(
where = "{}",
sort = "created_at",
page = 1,
- max_results = 20,
+ max_results = "",
} = query;
const filters = JSON.parse(where as string);
- const limit = parseInt(max_results as string, 10) || 20;
+ const limit = parseInt(max_results as string, 10) || 2000;
const skip = (parseInt(page as string, 10) - 1) * limit;
const sortField = sort.startsWith("-") ? sort.substring(1) : sort;