From de417e4757b606f2eea83fdf6881093c51ebd86d Mon Sep 17 00:00:00 2001 From: Mihoub Debache Date: Wed, 24 Apr 2024 13:49:51 +0200 Subject: [PATCH] feat(contributors & contact): merge contributors and contact page --- .github/workflows/staging.yml | 2 +- sib-api-v3-sdk.d.ts | 1 + src/api/api-operations/index.tsx | 0 src/api/contact-api/index.tsx | 0 .../useGetObjectContributeData.tsx | 1 - src/api/send-mail/index.tsx | 4 +- src/api/utils/buildURL.tsx | 31 ++++++ src/pages/contact-page/index.tsx | 16 ---- .../contribution-page/contribution-card.tsx | 38 +++----- .../contribution-page/contributor-info.tsx | 17 +--- src/pages/contribution-page/index.tsx | 71 +++++++++----- .../contribution-page/message-preview.tsx | 94 ++++++++++--------- src/pages/contribution-page/staff-action.tsx | 17 +--- src/pages/contribution-page/styles.scss | 23 +---- src/router.tsx | 3 +- src/types/contribution.ts | 32 ------- src/types/index.ts | 48 ++++++++++ 17 files changed, 207 insertions(+), 191 deletions(-) create mode 100644 sib-api-v3-sdk.d.ts delete mode 100644 src/api/api-operations/index.tsx delete mode 100644 src/api/contact-api/index.tsx create mode 100644 src/api/utils/buildURL.tsx delete mode 100644 src/pages/contact-page/index.tsx delete mode 100644 src/types/contribution.ts create mode 100644 src/types/index.ts diff --git a/.github/workflows/staging.yml b/.github/workflows/staging.yml index 0125f29..527a4f2 100644 --- a/.github/workflows/staging.yml +++ b/.github/workflows/staging.yml @@ -55,7 +55,7 @@ jobs: notify: name: 📢 Notify in mattermost channel - needs: deploy + needs: publish-ghcr if: always() runs-on: ubuntu-latest steps: diff --git a/sib-api-v3-sdk.d.ts b/sib-api-v3-sdk.d.ts new file mode 100644 index 0000000..54a6a3e --- /dev/null +++ b/sib-api-v3-sdk.d.ts @@ -0,0 +1 @@ +declare module "sib-api-v3-sdk"; diff --git a/src/api/api-operations/index.tsx b/src/api/api-operations/index.tsx deleted file mode 100644 index e69de29..0000000 diff --git a/src/api/contact-api/index.tsx b/src/api/contact-api/index.tsx deleted file mode 100644 index e69de29..0000000 diff --git a/src/api/contribution-api/useGetObjectContributeData.tsx b/src/api/contribution-api/useGetObjectContributeData.tsx index b2cf0ed..29f568a 100644 --- a/src/api/contribution-api/useGetObjectContributeData.tsx +++ b/src/api/contribution-api/useGetObjectContributeData.tsx @@ -26,7 +26,6 @@ function useGetContributionData(URL: {}, reload: unknown) { } } getData(); - console.log(data); }, [URL, reload]); return { data, isLoading, isError }; diff --git a/src/api/send-mail/index.tsx b/src/api/send-mail/index.tsx index 2a2269d..f7fe57a 100644 --- a/src/api/send-mail/index.tsx +++ b/src/api/send-mail/index.tsx @@ -1,10 +1,12 @@ import { useState } from "react"; import { Button, Text, TextArea } from "@dataesr/dsfr-plus"; import SibApiV3Sdk from "sib-api-v3-sdk"; +import { Contribution } from "../../types"; -function EmailSender({ contribution }) { +function EmailSender({ contribution }: { contribution: Contribution }) { const [emailSent, setEmailSent] = useState(false); const [response, setResponse] = useState(""); + const { VITE_BREVO_API_AUTHORIZATION } = import.meta.env; const sendEmail = async () => { diff --git a/src/api/utils/buildURL.tsx b/src/api/utils/buildURL.tsx new file mode 100644 index 0000000..0b6c13a --- /dev/null +++ b/src/api/utils/buildURL.tsx @@ -0,0 +1,31 @@ +import { useLocation } from "react-router-dom"; + +export const buildURL = ( + sort: string, + status: string, + query: string, + page: number, + searchInMessages: boolean = false +): string => { + const location = useLocation(); + const baseUrl = location.pathname.includes("contributionpage") + ? "contribute" + : "contact"; + const sorted = sort === "ASC" ? "sort=created_at" : "sort=-created_at"; + const where: any = {}; + if (query) { + where.$or = [ + { name: { $regex: `.*${query}.*`, $options: "i" } }, + searchInMessages && { + message: { $regex: `.*${query}.*`, $options: "i" }, + }, + ]; + } + if (["new", "ongoing", "treated"].includes(status)) { + where.status = status; + } + + return `https://scanr-api.dataesr.ovh/${baseUrl}?${sorted}&page=${page}&max_results=20&where=${JSON.stringify( + where + )}`; +}; diff --git a/src/pages/contact-page/index.tsx b/src/pages/contact-page/index.tsx deleted file mode 100644 index 9fce148..0000000 --- a/src/pages/contact-page/index.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { Accordion, AccordionGroup, Container, Text } from "@dataesr/dsfr-plus"; - -export default function ContactPage() { - return ( - - - - {" "} - Contribution via formulaire contact{" "} - - - Coucou par contribution via le formulaire de contact - - - ); -} diff --git a/src/pages/contribution-page/contribution-card.tsx b/src/pages/contribution-page/contribution-card.tsx index 2231ab0..497dfe7 100644 --- a/src/pages/contribution-page/contribution-card.tsx +++ b/src/pages/contribution-page/contribution-card.tsx @@ -1,4 +1,3 @@ -import { useState } from "react"; import { Accordion, AccordionGroup, @@ -12,22 +11,15 @@ import { import "./styles.scss"; import ContributorInfo from "./contributor-info"; import StaffActions from "./staff-action"; +import { Contribution } from "../../types"; -const ContributionItem = ({ data }: { data: any }) => { - const [showReplyForm, setShowReplyForm] = useState(false); - - const toggleReplyForm = () => { - setShowReplyForm(!showReplyForm); - }; - - const renderMessage = () => { - const messageLines = data.message.split("\n"); - if (messageLines.length <= 4) { - return data.message; - } else { - return messageLines.slice(8, 4).join("\n"); - } - }; +const ContributionItem = ({ + data, + highlightedQuery, +}: { + data: Contribution; + highlightedQuery: string; +}) => { const renderAccordion = () => ( @@ -38,7 +30,7 @@ const ContributionItem = ({ data }: { data: any }) => { color="purple-glycine" className="fr-mr-1w fr-mb-1w tag" > - {data?.tags?.join(", ")} + {data.tags.join(", ")} )} { Aucune réponse apportée à ce message pour l'instant )} - - + + ); diff --git a/src/pages/contribution-page/contributor-info.tsx b/src/pages/contribution-page/contributor-info.tsx index 0496246..9569b8e 100644 --- a/src/pages/contribution-page/contributor-info.tsx +++ b/src/pages/contribution-page/contributor-info.tsx @@ -1,21 +1,14 @@ +import { Contribution } from "../../types"; import MessagePreview from "./message-preview"; const ContributorInfo = ({ data, - renderMessage, - showDetails, + highlightedQuery, }: { - data: any; - renderMessage: any; - showDetails: any; + data: Contribution; + highlightedQuery: string; }) => { - return ( - - ); + return ; }; export default ContributorInfo; diff --git a/src/pages/contribution-page/index.tsx b/src/pages/contribution-page/index.tsx index a839413..3dde135 100644 --- a/src/pages/contribution-page/index.tsx +++ b/src/pages/contribution-page/index.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect, Key } from "react"; +import React, { useState, useEffect } from "react"; import { Button, Col, @@ -10,46 +10,55 @@ import { } from "@dataesr/dsfr-plus"; import ContributionItem from "./contribution-card"; import useGetContributionData from "../../api/contribution-api/useGetObjectContributeData"; +import { Contribution, ContributionPageProps } from "../../types"; +import { useLocation } from "react-router-dom"; +import { buildURL } from "../../api/utils/buildURL"; -type ContributionPageProps = { - url: string; -}; const ContributionPage: React.FC = () => { const [reload] = useState(0); const [sort, setSort] = useState("DESC"); const [status, setStatus] = useState("new"); const [query, setQuery] = useState(""); const [page, setPage] = useState(1); + const [searchInMessage, setSearchInMessage] = useState(false); + const [highlightedQuery, setHighlightedQuery] = useState(""); - const buildURL = () => { - const sorted = sort === "ASC" ? "sort=created_at" : "sort=-created_at"; - const where: any = {}; - if (query) { - where.data = { $text: { $search: query } }; - } - if (["new", "ongoing", "treated"].includes(status)) { - where.status = status; - } - - return `https://scanr-api.dataesr.ovh/contribute?${sorted}&page=${page}&max_results=20&where=${JSON.stringify( - where - )}`; - }; + const location = useLocation(); const { data, isLoading, isError } = useGetContributionData( - buildURL(), + buildURL(sort, status, query, page, searchInMessage), reload ); + useEffect(() => { setPage(1); - }, [reload]); + }, [reload, location.pathname]); const meta = (data as { meta: any }).meta; const maxPage = meta ? Math.ceil(meta.total / 10) : 1; - const contrib = (data as { data: any }).data; + const contrib: Contribution[] = (data as { data: Contribution[] }).data; - if (isLoading) return LOADING; - if (isError) return ERROR; + const handleSearch = (value: string) => { + setQuery(value.trim()); + setHighlightedQuery(value.trim()); + }; + console.log(highlightedQuery); + + const filteredContributions = contrib?.filter((contribution) => { + const nameMatches = contribution.name + .toLowerCase() + .includes(query.toLowerCase()); + if (searchInMessage) { + const messageMatches = contribution.message + .toLowerCase() + .includes(query.toLowerCase()); + return nameMatches || messageMatches; + } + return nameMatches; + }); + + if (isLoading) return LOADING; + if (isError) return ERROR; return ( @@ -58,7 +67,7 @@ const ContributionPage: React.FC = () => { setQuery(e.target.value)} + onSearch={(value) => handleSearch(value || "")} isLarge buttonLabel="Rechercher" placeholder="Rechercher par nom" @@ -109,10 +118,20 @@ const ContributionPage: React.FC = () => { + setSearchInMessage(e.target.checked)} + /> + - {contrib.map((contribution: { _id: Key | null | undefined }) => ( - + {filteredContributions.map((contribution) => ( + ))} - )} - {showReplyForm && } + {data.comment && Réponse : {data.comment}} ); diff --git a/src/pages/contribution-page/styles.scss b/src/pages/contribution-page/styles.scss index 25c78c8..97a5ae6 100644 --- a/src/pages/contribution-page/styles.scss +++ b/src/pages/contribution-page/styles.scss @@ -3,7 +3,7 @@ border: 1px solid var(--background-alt-green-emeraude); border-radius: 10px; margin-bottom: 10px; - margin-right: 100px; + margin-right: 200px; padding: 20px; } .staffSide { @@ -21,23 +21,10 @@ margin-bottom: 20px; } -.message-info { - display: flex; - justify-content: space-between; - flex-wrap: wrap; -} - -.info-group { - display: flex; - flex-direction: row; - align-items: flex-start; - flex-wrap: wrap; -} - -.info-item { - flex: 0 0 50%; - padding-right: 20px; -} .accordion { width: 100%; } +.contributorInfo { + width: 100%; + text-align: right; +} diff --git a/src/router.tsx b/src/router.tsx index 5aaf418..aabf662 100644 --- a/src/router.tsx +++ b/src/router.tsx @@ -2,7 +2,6 @@ import { Route, Routes } from "react-router-dom"; import Layout from "./layout"; import Home from "./pages/home"; -import ContactPage from "./pages/contact-page"; import ApiOperationPage from "./pages/api-operation-page"; import ContributionPage from "./pages/contribution-page"; @@ -15,7 +14,7 @@ export default function Router() { path="/contributionPage" element={} /> - } /> + } /> } /> diff --git a/src/types/contribution.ts b/src/types/contribution.ts deleted file mode 100644 index 55947a1..0000000 --- a/src/types/contribution.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { ReactNode } from "react"; - -export type Contribution = { - message: ReactNode; - created_at: string | number | Date; - fonction: any; - organisation: any; - email: any; - name: any; - type: string; - id: string; - data: { - idref: any; - tags: any; - id: string; - type: string; - section: string; - comment: string; - name: string; - organisation: string; - email: string; - fonction: string; - message: string; - modifier_at: string; - created_at: string; - status: string; - team: any[]; - }[]; - meta: { - total: number; - }; -}; diff --git a/src/types/index.ts b/src/types/index.ts new file mode 100644 index 0000000..2841a67 --- /dev/null +++ b/src/types/index.ts @@ -0,0 +1,48 @@ +export type Contribution = { + status: string; + tags: any; + message: string; + created_at: string | number | Date; + fonction: any; + organisation: any; + email: any; + name: any; + type: string; + id: string; + comment: string; + data: ContributionData[]; + meta: { + total: number; + }; + highlightedQuery: string; +}; + +export type ContributionData = { + idref: any; + tags: any; + id: string; + type: string; + section: string; + comment: string; + name: string; + organisation: string; + email: string; + fonction: string; + message: string; + modifier_at: string; + created_at: string; + status: string; + team: any[]; +}; + +export type ContributionPageProps = { + url: string; +}; + +export type StaffActionsProps = { + data: []; +}; + +export type MessagePreviewProps = { + renderMessage: any; +};