-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(last-mails-sent): add last mails sent route and ui
- Loading branch information
Showing
15 changed files
with
390 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { useQuery } from "@tanstack/react-query"; | ||
import { postHeaders } from "../../config/api"; | ||
|
||
const useSentEmails = () => { | ||
const fetchSentEmails = async () => { | ||
const response = await fetch("/api/get-sent-emails", { | ||
headers: postHeaders, | ||
}); | ||
if (!response.ok) { | ||
throw new Error("Network response was not ok"); | ||
} | ||
return response.json(); | ||
}; | ||
|
||
const { data, isLoading, isError, refetch } = useQuery( | ||
["sentEmails"], | ||
fetchSentEmails | ||
); | ||
console.log(data); | ||
return { data, isLoading, isError, refetch }; | ||
}; | ||
|
||
export default useSentEmails; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import React, { useState } from "react"; | ||
import { Badge, Col, Text, Title } from "@dataesr/dsfr-plus"; | ||
import { FaCopy } from "react-icons/fa"; | ||
import "./styles.scss"; | ||
import { LastMailsSentProps } from "../../../types"; | ||
import collectionNameMapping, { generateLink } from "./utils"; | ||
|
||
const LastMailsSentItem: React.FC<LastMailsSentProps> = ({ data }) => { | ||
const [copiedId, setCopiedId] = useState<string | null>(null); | ||
|
||
const copyToClipboard = (text: string) => { | ||
navigator.clipboard.writeText(text).then(() => { | ||
setCopiedId(text); | ||
setTimeout(() => setCopiedId(null), 2000); | ||
}); | ||
}; | ||
|
||
return ( | ||
<> | ||
{data.emails.map((email, index) => { | ||
const link = generateLink( | ||
email.collectionName, | ||
email.fromApplication, | ||
email.contributionId | ||
); | ||
|
||
const sentDate = new Date(email.sentAt); | ||
const formattedDate = sentDate.toLocaleDateString("fr-FR"); | ||
const formattedTime = sentDate.toLocaleTimeString("fr-FR", { | ||
hour: "2-digit", | ||
minute: "2-digit", | ||
}); | ||
|
||
return ( | ||
<Col key={index} className="email-item fr-mb-2w"> | ||
<div className="badges"> | ||
<Badge | ||
size="sm" | ||
color="green-menthe" | ||
className="fr-mr-1w fr-mb-1w" | ||
> | ||
{collectionNameMapping[email.collectionName]} | ||
</Badge> | ||
|
||
{email.fromApplication && ( | ||
<Badge | ||
size="sm" | ||
color="blue-ecume" | ||
className="fr-mr-1w fr-mb-1w" | ||
> | ||
{email.fromApplication} | ||
</Badge> | ||
)} | ||
</div> | ||
|
||
<div className="email-content"> | ||
<Title look="h6" as="h3" className="fr-mb-0"> | ||
Réponse de <i>{email.selectedProfile}</i> à{" "} | ||
<i> | ||
{email?.name} ({email?.to}) | ||
</i> | ||
</Title> | ||
<Text size="sm"> | ||
<a href={link} target="_blank" rel="noopener noreferrer"> | ||
<i>{email?.contributionId}</i> | ||
</a> | ||
<button | ||
className={`copy-button ${ | ||
copiedId === email.contributionId ? "copied" : "" | ||
}`} | ||
onClick={() => copyToClipboard(email.contributionId)} | ||
title="Copier l'ID" | ||
> | ||
{copiedId === email.contributionId && ( | ||
<span className="copied-text">Copié</span> | ||
)} | ||
<FaCopy size={14} color="#2196f3" className="copy-icon" /> | ||
</button> | ||
</Text> | ||
<Text size="sm"> | ||
<i> | ||
Envoyé le {formattedDate} à {formattedTime} | ||
</i> | ||
</Text> | ||
<Text>{email.userResponse}</Text> | ||
</div> | ||
</Col> | ||
); | ||
})} | ||
</> | ||
); | ||
}; | ||
|
||
export default LastMailsSentItem; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { Col } from "@dataesr/dsfr-plus"; | ||
|
||
const Selectors = ({ uniqueProfiles, setStatus }) => { | ||
const handleProfileChange = (event) => { | ||
setStatus(event.target.value); | ||
}; | ||
|
||
return ( | ||
<Col> | ||
<Col className="fr-mb-1w"> | ||
<select onChange={handleProfileChange} className="fr-select"> | ||
<option value="choose">Par</option> | ||
{uniqueProfiles.map((profile, index) => ( | ||
<option key={index} value={profile}> | ||
{profile} | ||
</option> | ||
))} | ||
</select> | ||
</Col> | ||
</Col> | ||
); | ||
}; | ||
|
||
export default Selectors; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
.email-item { | ||
background-color: #f1f4f8; | ||
padding: 1.5rem; | ||
border-radius: 8px; | ||
margin-top: 1rem; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
const collectionNameMapping: { [key: string]: string } = { | ||
contribute: "Contribution par objets", | ||
contacts: "Formulaire de contact", | ||
contribute_productions: "Lier des publications", | ||
"remove-user": "Retirer de la base de données", | ||
"update-user-data": "Changement de nom", | ||
}; | ||
|
||
export default collectionNameMapping; | ||
// utils/generateLink.ts | ||
export function generateLink( | ||
collectionName: string, | ||
fromApplication?: string, | ||
id?: string | ||
): 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 (collectionName === "contacts" && fromApplication) { | ||
basePath = basePathMap[collectionName][fromApplication] || ""; | ||
} else { | ||
basePath = (basePathMap[collectionName] as string) || ""; | ||
} | ||
|
||
return id | ||
? `${basePath}?page=1&query=${id}&searchInMessage=false&sort=DESC&status=choose` | ||
: basePath; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import { useState, useEffect } from "react"; | ||
import { useLocation } from "react-router-dom"; | ||
import { Col, Container, Row, Text, Title } from "@dataesr/dsfr-plus"; | ||
import { Contribution } from "../../types"; | ||
import BottomPaginationButtons from "../../components/pagination/bottom-buttons"; | ||
import TopPaginationButtons from "../../components/pagination/top-buttons"; | ||
import useSentEmails from "../../api/contribution-api/getSentMails"; | ||
import LastMailsSentItem from "./components/item"; | ||
import Selectors from "./components/selectors"; | ||
|
||
const LastMailsSent: React.FC = () => { | ||
const location = useLocation(); | ||
const [sort, setSort] = useState("DESC"); | ||
const [status, setStatus] = useState("choose"); | ||
const [query, setQuery] = useState<string[]>([]); | ||
const [page, setPage] = useState(1); | ||
const [searchInMessage, setSearchInMessage] = useState(false); | ||
|
||
const { data, isLoading, isError } = useSentEmails(); | ||
const sentEmails: Contribution[] = data ? data.emails : []; | ||
const maxPage = Math.ceil((data?.emails.length || 0) / 10); | ||
|
||
const uniqueProfiles = Array.from( | ||
new Set(sentEmails.map((email) => email.selectedProfile)) | ||
); | ||
|
||
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"); | ||
}, [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); | ||
if (status !== "choose") { | ||
newSearchParams.set("status", status); | ||
} | ||
const newURL = `${window.location.pathname}?${newSearchParams.toString()}`; | ||
window.history.pushState({}, "", newURL); | ||
}, [page, query, searchInMessage, sort, status]); | ||
|
||
if (isLoading) | ||
return ( | ||
<Container className="fr-my-5w"> | ||
<Text>Chargement...</Text> | ||
</Container> | ||
); | ||
|
||
if (isError) | ||
return ( | ||
<Container className="fr-my-5w"> | ||
<Text>Erreur lors du chargement des emails envoyés.</Text> | ||
</Container> | ||
); | ||
|
||
return ( | ||
<Container className="fr-my-5w"> | ||
<Title as="h1">Derniers mails envoyés</Title> | ||
<Row gutters className="fr-mb-3w"> | ||
<Col> | ||
<TopPaginationButtons | ||
meta={{ total: sentEmails.length }} | ||
page={page} | ||
maxPage={maxPage} | ||
setPage={setPage} | ||
/> | ||
</Col> | ||
<Col offsetLg="6"> | ||
<Selectors setStatus={setStatus} uniqueProfiles={uniqueProfiles} /> | ||
</Col> | ||
</Row> | ||
<Row> | ||
<Col> | ||
<LastMailsSentItem data={data} /> | ||
</Col> | ||
</Row> | ||
<BottomPaginationButtons | ||
page={page} | ||
maxPage={maxPage} | ||
setPage={setPage} | ||
/> | ||
</Container> | ||
); | ||
}; | ||
|
||
export default LastMailsSent; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { Elysia } from "elysia"; | ||
import { MongoClient } from "mongodb"; | ||
import { errorSchema } from "../../../schemas/errors/errorSchema"; | ||
|
||
const MONGO_URI = process.env.MONGO_URI || ""; | ||
const DB_NAME = process.env.MONGO_DATABASE || ""; | ||
|
||
const client = new MongoClient(MONGO_URI); | ||
await client.connect(); | ||
const db = client.db(DB_NAME); | ||
|
||
const lastSentMail = new Elysia(); | ||
|
||
lastSentMail.get( | ||
"/get-sent-emails", | ||
async () => { | ||
const sentEmailsCollection = db.collection("sent_emails"); | ||
|
||
const sentEmails = await sentEmailsCollection.find().toArray(); | ||
|
||
return { | ||
emails: sentEmails, | ||
}; | ||
}, | ||
{ | ||
response: { | ||
401: errorSchema, | ||
500: errorSchema, | ||
}, | ||
detail: { | ||
summary: "Récupérer les emails envoyés", | ||
description: | ||
"Cette route permet de récupérer la liste des emails envoyés et enregistrés dans la collection 'sent_emails' de MongoDB.", | ||
tags: ["Emails"], | ||
}, | ||
} | ||
); | ||
|
||
export default lastSentMail; |
Oops, something went wrong.