diff --git a/src/api/utils/buildURL.tsx b/src/api/utils/buildURL.tsx index be1158d..11a4ef7 100644 --- a/src/api/utils/buildURL.tsx +++ b/src/api/utils/buildURL.tsx @@ -7,13 +7,18 @@ export const buildURL = ( searchInMessages: boolean = false ): string => { const isDevelopment = import.meta.env.VITE_HEADER_TAG === "Development"; + const ticketOfficeApi = import.meta.env.BASE_API_URL; const baseApiUrl = isDevelopment ? "http://localhost:3000/api" - : "https://ticket-office-api.staging.dataesr.ovh/api"; + : `${ticketOfficeApi}/api`; let baseUrl = "contact"; if (location?.pathname?.includes("contributionpage")) { baseUrl = "contribute"; + } else if (location?.pathname?.includes("removeuser")) { + baseUrl = "remove-user"; + } else if (location?.pathname?.includes("namechange")) { + baseUrl = "update-user-data"; } else if (location?.pathname?.includes("apioperations")) { baseUrl = "production"; } @@ -33,7 +38,9 @@ export const buildURL = ( ]; if (searchInMessages) { - where.$or.push({ message: { $regex: `.*${query}.*`, $options: "i" } }); + where.$or.push({ + message: { $regex: `.*${query}.*`, $options: "i" }, + }); } } } diff --git a/src/config/api.ts b/src/config/api.ts index 8caa380..a2943b9 100644 --- a/src/config/api.ts +++ b/src/config/api.ts @@ -1,6 +1,5 @@ const API_KEY = import.meta.env.VITE_SCANR_API_AUTHORIZATION; const isDevelopment = import.meta.env.VITE_HEADER_TAG === "Development"; -console.log(`API_KEY: ${API_KEY}`); export const headers = API_KEY ? { Authorization: `Basic ${API_KEY}` } : {}; export const postHeaders = { ...headers, @@ -18,3 +17,11 @@ export const contactUrl = isDevelopment export const productionUrl = isDevelopment ? "http://localhost:3000/api/production?max_results=2000" : "https://ticket-office-api.staging.dataesr.ovh/api/productionsmax_results=2000"; + +export const nameChangeUrl = isDevelopment + ? "http://localhost:3000/api/update-user-data?max_results=2000" + : "https://ticket-office-api.staging.dataesr.ovh/api/update-user-datamax_results=2000"; + +export const removeUserUrl = isDevelopment + ? "http://localhost:3000/api/remove-user?max_results=2000" + : "https://ticket-office-api.staging.dataesr.ovh/api/remove-usermax_results=2000"; diff --git a/src/layout/header.tsx b/src/layout/header.tsx index d974e11..f41d376 100644 --- a/src/layout/header.tsx +++ b/src/layout/header.tsx @@ -109,7 +109,10 @@ const Header: React.FC = () => { > Lier des publications - + Supprimer des personnes de la base de données = () => { + const [sort, setSort] = useState("DESC"); + const [status, setStatus] = useState("choose"); + const [query, setQuery] = useState([]); + const [page, setPage] = useState(1); + const [searchInMessage, setSearchInMessage] = useState(false); + const [highlightedQuery, setHighlightedQuery] = useState(""); + const [selectedContribution, setSelectedContribution] = useState(""); + const location = useLocation(); + useEffect(() => { + const params = new URLSearchParams(location.search); + setPage(parseInt(params.get("page") || "1")); + setSearchInMessage(params.get("searchInMessage") === "true"); + const queryParam = params.get("query") || ""; + setQuery(queryParam ? queryParam.split(",") : []); + setSort(params.get("sort") || "DESC"); + setStatus(params.get("status") || "choose"); + }, [location.search]); + + useEffect(() => { + const newSearchParams = new URLSearchParams(); + newSearchParams.set("page", page.toString()); + newSearchParams.set("query", query.join(",")); + newSearchParams.set("searchInMessage", searchInMessage.toString()); + newSearchParams.set("sort", sort); + newSearchParams.set("status", status); + + const newURL = `${window.location.pathname}?${newSearchParams.toString()}`; + window.history.pushState({}, "", newURL); + }, [page, query, searchInMessage, sort, status]); + + const url = buildURL(location, sort, status, query.join(" "), page); + console.log(url); + let urlToSend = nameChangeUrl; + const { data, isLoading, isError, refetch } = ContributionData(url); + const getTags = ContributionData(urlToSend); + const allTags = getTags?.data?.map((tag) => tag?.tags); + const meta = (data as { meta: any })?.meta; + const maxPage = meta ? Math.ceil(meta.total / 10) : 1; + const contributions: ChangeNameProps[] = data; + + useEffect(() => { + if (contributions && contributions.length > 0) { + setSelectedContribution((prevSelectedContribution) => { + const isValid = contributions.some( + (contribution) => contribution._id === prevSelectedContribution + ); + return isValid ? prevSelectedContribution : contributions[0]?._id; + }); + } + }, [contributions]); + + const handleSearch = (value: string) => { + const trimmedValue = value.trim(); + if (trimmedValue !== "" && !query.includes(trimmedValue)) { + setQuery([...query, trimmedValue]); + setHighlightedQuery(trimmedValue); + } + }; + + const handleRemoveQueryItem = (item: string) => { + setQuery(query.filter((q) => q !== item)); + }; + + const onSelectContribution = (id: string) => { + setSelectedContribution(id); + }; + + const filteredContributions = contributions?.filter((contribution) => { + if (query.length === 0) { + return true; + } + const queryLower = query.map((q) => q.toLowerCase()); + const nameMatches = queryLower.some((q) => + contribution.name.toLowerCase().includes(q) + ); + const idMatches = queryLower.some((q) => + contribution._id.toLowerCase().includes(q) + ); + if (searchInMessage) { + const messageMatches = queryLower.some((q) => + contribution.message.toLowerCase().includes(q) + ); + return nameMatches || idMatches || messageMatches; + } + return nameMatches || idMatches; + }); + + if (isLoading) + return ( + + Chargement... + + ); + + if (isError) + return ( + + Erreur lors du chargement des données. + + ); -const ChangeNamePage = () => { return ( - - Changer le nom des personnes de la base de donnée + + Demande de changement de nom + + + handleSearch(value || "")} + isLarge + buttonLabel="Rechercher" + placeholder="Rechercher par nom ou ID" + /> +
+ {query + .filter((item) => item.trim() !== "") + .map((item, index) => ( + handleRemoveQueryItem(item)} + > + {item} + + ))} +
+ + + + + +
+ + + + + + {filteredContributions && filteredContributions.length > 0 && ( + contribution?._id === selectedContribution + )} + refetch={refetch} + highlightedQuery={highlightedQuery} + /> + )} + + +
); }; diff --git a/src/pages/delete-persons/index.tsx b/src/pages/delete-persons/index.tsx index 620b256..7a2eceb 100644 --- a/src/pages/delete-persons/index.tsx +++ b/src/pages/delete-persons/index.tsx @@ -1,11 +1,198 @@ -import { Container, Title } from "@dataesr/dsfr-plus"; +import { useState, useEffect } from "react"; +import { useLocation } from "react-router-dom"; +import { + Col, + Container, + Row, + Text, + Title, + SearchBar, + DismissibleTag, +} from "@dataesr/dsfr-plus"; +import ContributionData from "../../api/contribution-api/getData"; +import { RemoveUserPageProps, RemoveUserProps } from "../../types"; +import BottomPaginationButtons from "../../components/pagination/bottom-buttons"; +import TopPaginationButtons from "../../components/pagination/top-buttons"; +import Selectors from "../../components/selectors"; +import { removeUserUrl } from "../../config/api"; +import ContributorSummary from "../contribution-page/contributor-summary"; +import ContributionItem from "../contribution-page/contribution-item"; +import { buildURL } from "../../api/utils/buildURL"; + +const RemoveUserPage: React.FC = () => { + const [sort, setSort] = useState("DESC"); + const [status, setStatus] = useState("choose"); + const [query, setQuery] = useState([]); + const [page, setPage] = useState(1); + const [searchInMessage, setSearchInMessage] = useState(false); + const [highlightedQuery, setHighlightedQuery] = useState(""); + const [selectedContribution, setSelectedContribution] = useState(""); + const location = useLocation(); + useEffect(() => { + const params = new URLSearchParams(location.search); + setPage(parseInt(params.get("page") || "1")); + setSearchInMessage(params.get("searchInMessage") === "true"); + const queryParam = params.get("query") || ""; + setQuery(queryParam ? queryParam.split(",") : []); + setSort(params.get("sort") || "DESC"); + setStatus(params.get("status") || "choose"); + }, [location.search]); + + useEffect(() => { + const newSearchParams = new URLSearchParams(); + newSearchParams.set("page", page.toString()); + newSearchParams.set("query", query.join(",")); + newSearchParams.set("searchInMessage", searchInMessage.toString()); + newSearchParams.set("sort", sort); + newSearchParams.set("status", status); + + const newURL = `${window.location.pathname}?${newSearchParams.toString()}`; + window.history.pushState({}, "", newURL); + }, [page, query, searchInMessage, sort, status]); + + const url = buildURL(location, sort, status, query.join(" "), page); + + let urlToSend = removeUserUrl; + const { data, isLoading, isError, refetch } = ContributionData(url); + const getTags = ContributionData(urlToSend); + const allTags = getTags?.data?.map((tag) => tag?.tags); + const meta = (data as { meta: any })?.meta; + const maxPage = meta ? Math.ceil(meta.total / 10) : 1; + const contributions: RemoveUserProps[] = data; + + useEffect(() => { + if (contributions && contributions.length > 0) { + setSelectedContribution((prevSelectedContribution) => { + const isValid = contributions.some( + (contribution) => contribution._id === prevSelectedContribution + ); + return isValid ? prevSelectedContribution : contributions[0]?._id; + }); + } + }, [contributions]); + + const handleSearch = (value: string) => { + const trimmedValue = value.trim(); + if (trimmedValue !== "" && !query.includes(trimmedValue)) { + setQuery([...query, trimmedValue]); + setHighlightedQuery(trimmedValue); + } + }; + + const handleRemoveQueryItem = (item: string) => { + setQuery(query.filter((q) => q !== item)); + }; + + const onSelectContribution = (id: string) => { + setSelectedContribution(id); + }; + + const filteredContributions = contributions?.filter((contribution) => { + if (query.length === 0) { + return true; + } + const queryLower = query.map((q) => q.toLowerCase()); + const nameMatches = queryLower.some((q) => + contribution.name.toLowerCase().includes(q) + ); + const idMatches = queryLower.some((q) => + contribution._id.toLowerCase().includes(q) + ); + if (searchInMessage) { + const messageMatches = queryLower.some((q) => + contribution.message.toLowerCase().includes(q) + ); + return nameMatches || idMatches || messageMatches; + } + return nameMatches || idMatches; + }); + + if (isLoading) + return ( + + Chargement... + + ); + + if (isError) + return ( + + Erreur lors du chargement des données. + + ); -const DeletePage = () => { return ( - - Supprimer des personnes de la base de donnée + + Demande de suppression de profil + + + handleSearch(value || "")} + isLarge + buttonLabel="Rechercher" + placeholder="Rechercher par nom ou ID" + /> +
+ {query + .filter((item) => item.trim() !== "") + .map((item, index) => ( + handleRemoveQueryItem(item)} + > + {item} + + ))} +
+ + + + + +
+ + + + + + {filteredContributions && filteredContributions.length > 0 && ( + contribution?._id === selectedContribution + )} + refetch={refetch} + highlightedQuery={highlightedQuery} + /> + )} + + +
); }; -export default DeletePage; +export default RemoveUserPage; diff --git a/src/router.tsx b/src/router.tsx index b646a93..45cecaa 100644 --- a/src/router.tsx +++ b/src/router.tsx @@ -3,9 +3,9 @@ import { Route, Routes } from "react-router-dom"; import Home from "./pages/home"; import ApiOperationPage from "./pages/api-operation-page/link-publications"; import ContributionPage from "./pages/contribution-page"; -import DeletePage from "./pages/delete-persons"; import ChangeNamePage from "./pages/change-name"; import Layout from "./layout"; +import RemoveUserPage from "./pages/delete-persons"; export default function Router() { return ( @@ -18,8 +18,8 @@ export default function Router() { /> } /> } /> - } /> - } /> + } /> + } /> ); diff --git a/src/types/index.ts b/src/types/index.ts index 35c37f6..b32c32a 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -16,6 +16,61 @@ export interface Contribution { modified_at?: string; threads?: Thread[]; } +export interface ChangeNameProps { + _id: string; + id: string; + name: string; + email: string; + phone: string; + tags: string[]; + status: string; + comment?: string; + team?: string[]; + type: string; + created_at: string; + message: string; + organisation?: string; + fonction?: string; + modified_at?: string; + threads?: Thread[]; +} + +export interface RemoveUserProps { + _id: string; + id: string; + name: string; + email: string; + phone: string; + tags: string[]; + status: string; + comment?: string; + team?: string[]; + type: string; + created_at: string; + message: string; + organisation?: string; + fonction?: string; + modified_at?: string; + threads?: Thread[]; +} +export interface ChangeNameContribution { + _id: string; + id: string; + name: string; + email: string; + phone: string; + tags: string[]; + status: string; + comment?: string; + team?: string[]; + type: string; + created_at: string; + message: string; + organisation?: string; + fonction?: string; + modified_at?: string; + threads?: Thread[]; +} export interface Thread { team: [string]; @@ -54,6 +109,12 @@ export type ContributionDataType = { export type ContributionPageProps = { url: string; }; +export type ChangeNamePageProps = { + url: string; +}; +export type RemoveUserPageProps = { + url: string; +}; export type StaffActionsProps = { data: any[];