From c16b71483b06483a0db16f9c82a073d5067c2df1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20PAILHAREY?= <rpailharey@grandlyon.com>
Date: Thu, 27 Apr 2023 08:42:23 +0000
Subject: [PATCH] feat(custom-popup): use wysiwyg editor

---
 .vscode/settings.json                         |  4 +-
 src/components/Newsletter/CustomEditor.tsx    | 23 +++++---
 .../Newsletter/ImagePicker/ImagePicker.tsx    | 13 +----
 .../Newsletter/MailSubject/mailSubject.tsx    |  6 +-
 .../Newsletter/MonthlyInfo/MonthlyInfo.tsx    | 16 +-----
 .../Newsletter/MonthlyNews/MonthlyNews.tsx    |  9 +--
 src/components/Newsletter/Newsletter.tsx      | 57 +++++++++----------
 src/components/Newsletter/Poll/Poll.tsx       |  9 +--
 src/components/Popups/Popups.tsx              | 33 +++++------
 src/components/Popups/popups.scss             |  6 +-
 10 files changed, 73 insertions(+), 103 deletions(-)

diff --git a/.vscode/settings.json b/.vscode/settings.json
index e8686e1b..5ecf35bd 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -22,7 +22,9 @@
   "editor.formatOnSave": true,
   "eslint.format.enable": true,
   "editor.codeActionsOnSave": {
-    "source.fixAll.eslint": true
+    "source.fixAll.eslint": true,
+    "source.fixAll": true,
+    "source.organizeImports": true
   },
   "editor.defaultFormatter": "esbenp.prettier-vscode",
   "peacock.color": "#2aa63d",
diff --git a/src/components/Newsletter/CustomEditor.tsx b/src/components/Newsletter/CustomEditor.tsx
index 5e0bfa08..b9867c75 100644
--- a/src/components/Newsletter/CustomEditor.tsx
+++ b/src/components/Newsletter/CustomEditor.tsx
@@ -5,19 +5,26 @@ import { Editor, EditorState } from 'react-draft-wysiwyg'
 import CustomLink from './CustomLink'
 import './customEditor.scss'
 
+export type EditorType =
+  | 'info'
+  | 'title'
+  | 'content'
+  | 'question'
+  | 'link'
+  | 'subject'
+  | 'image'
+  | 'custom_popup'
+
 interface CustomEditorProps {
   baseState: EditorState
-  editorType: 'info' | 'title' | 'content' | 'question' | 'link' | 'subject'
-  handleChange: (
-    value: string,
-    type: 'info' | 'title' | 'content' | 'question' | 'link' | 'subject'
-  ) => void
+  type: EditorType
+  handleChange: (value: string, type: EditorType) => void
 }
 
 const CustomEditor: React.FC<CustomEditorProps> = ({
   baseState,
   handleChange,
-  editorType,
+  type,
 }) => {
   const [editorState, setEditorState] = useState<EditorState>(baseState)
 
@@ -45,9 +52,9 @@ const CustomEditor: React.FC<CustomEditorProps> = ({
     (state: EditorState) => {
       setEditorState(state)
       const htmlState = convertStateToHTML(state)
-      handleChange(htmlState, editorType)
+      handleChange(htmlState, type)
     },
-    [editorType, handleChange]
+    [type, handleChange]
   )
 
   return (
diff --git a/src/components/Newsletter/ImagePicker/ImagePicker.tsx b/src/components/Newsletter/ImagePicker/ImagePicker.tsx
index 2e9f6c27..33a85e80 100644
--- a/src/components/Newsletter/ImagePicker/ImagePicker.tsx
+++ b/src/components/Newsletter/ImagePicker/ImagePicker.tsx
@@ -3,22 +3,13 @@ import React, { useContext, useEffect, useState } from 'react'
 import { getAxiosXSRFHeader } from '../../../axios.config'
 import { UserContext, UserContextProps } from '../../../hooks/userContext'
 import { NewsletterService } from '../../../services/newsletter.service'
+import { EditorType } from '../CustomEditor'
 import Modal from '../Modal/Modal'
 import SingleImage from './SingleImage'
 
 interface ImagePickerProps {
   imageURL: string
-  handleChange: (
-    value: string,
-    type:
-      | 'info'
-      | 'title'
-      | 'content'
-      | 'question'
-      | 'link'
-      | 'image'
-      | 'subject'
-  ) => void
+  handleChange: (value: string, type: EditorType) => void
 }
 
 const ImagePicker: React.FC<ImagePickerProps> = ({
diff --git a/src/components/Newsletter/MailSubject/mailSubject.tsx b/src/components/Newsletter/MailSubject/mailSubject.tsx
index 1b3374b2..bf6443b9 100644
--- a/src/components/Newsletter/MailSubject/mailSubject.tsx
+++ b/src/components/Newsletter/MailSubject/mailSubject.tsx
@@ -1,4 +1,5 @@
 import React, { ChangeEvent } from 'react'
+import { EditorType } from '../CustomEditor'
 import { ContentItems } from '../Newsletter'
 import './mailSubject.scss'
 
@@ -6,10 +7,7 @@ interface MailSubjectProps {
   onSave: () => Promise<void>
   onCancel: () => void
   subject: string
-  handleChange: (
-    value: string,
-    type: 'info' | 'title' | 'content' | 'question' | 'link' | 'subject'
-  ) => void
+  handleChange: (value: string, type: EditorType) => void
   onDelete: (target: ContentItems) => void
 }
 const MailSubject: React.FC<MailSubjectProps> = ({
diff --git a/src/components/Newsletter/MonthlyInfo/MonthlyInfo.tsx b/src/components/Newsletter/MonthlyInfo/MonthlyInfo.tsx
index ec98ab25..d7d8a277 100644
--- a/src/components/Newsletter/MonthlyInfo/MonthlyInfo.tsx
+++ b/src/components/Newsletter/MonthlyInfo/MonthlyInfo.tsx
@@ -1,7 +1,7 @@
 import React from 'react'
 import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css'
 import { convertStringToEditorState } from '../../../utils/editorStateManagement'
-import CustomEditor from '../CustomEditor'
+import CustomEditor, { EditorType } from '../CustomEditor'
 import ImagePicker from '../ImagePicker/ImagePicker'
 import { ContentItems } from '../Newsletter'
 import './monthlyInfo.scss'
@@ -10,17 +10,7 @@ interface MonthlyInfoProps {
   onSave: () => Promise<void>
   onCancel: () => void
   info: string
-  handleChange: (
-    value: string,
-    type:
-      | 'info'
-      | 'title'
-      | 'content'
-      | 'question'
-      | 'link'
-      | 'image'
-      | 'subject'
-  ) => void
+  handleChange: (value: string, type: EditorType) => void
   onDelete: (target: ContentItems) => void
   imageURL: string
 }
@@ -42,7 +32,7 @@ const MonthlyInfo: React.FC<MonthlyInfoProps> = ({
         <CustomEditor
           baseState={convertStringToEditorState(info)}
           handleChange={handleChange}
-          editorType="info"
+          type="info"
         />
         <div className="buttons">
           <button className="btnCancel" onClick={onCancel}>
diff --git a/src/components/Newsletter/MonthlyNews/MonthlyNews.tsx b/src/components/Newsletter/MonthlyNews/MonthlyNews.tsx
index f4fdbc58..90557d31 100644
--- a/src/components/Newsletter/MonthlyNews/MonthlyNews.tsx
+++ b/src/components/Newsletter/MonthlyNews/MonthlyNews.tsx
@@ -1,7 +1,7 @@
 import React, { ChangeEvent } from 'react'
 import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css'
 import { convertStringToEditorState } from '../../../utils/editorStateManagement'
-import CustomEditor from '../CustomEditor'
+import CustomEditor, { EditorType } from '../CustomEditor'
 import { ContentItems } from '../Newsletter'
 import './monthlyNews.scss'
 
@@ -10,10 +10,7 @@ interface MonthlyNewsProps {
   onCancel: () => void
   title: string
   content: string
-  handleChange: (
-    value: string,
-    type: 'info' | 'title' | 'content' | 'question' | 'link' | 'subject'
-  ) => void
+  handleChange: (value: string, type: EditorType) => void
   onDelete: (target: ContentItems) => void
 }
 const MonthlyNews: React.FC<MonthlyNewsProps> = ({
@@ -44,7 +41,7 @@ const MonthlyNews: React.FC<MonthlyNewsProps> = ({
           <CustomEditor
             baseState={convertStringToEditorState(content)}
             handleChange={handleChange}
-            editorType="content"
+            type="content"
           />
         </div>
 
diff --git a/src/components/Newsletter/Newsletter.tsx b/src/components/Newsletter/Newsletter.tsx
index 7e902395..774fe1dd 100644
--- a/src/components/Newsletter/Newsletter.tsx
+++ b/src/components/Newsletter/Newsletter.tsx
@@ -13,6 +13,7 @@ import { IMonthlyNews } from '../../models/monthlyNews.model'
 import { IPoll } from '../../models/poll.model'
 import { NewsletterService } from '../../services/newsletter.service'
 import Loader from '../Loader/Loader'
+import { EditorType } from './CustomEditor'
 import DateSelector from './DateSelector/DateSelector'
 import MailSubject from './MailSubject/mailSubject'
 import Modal from './Modal/Modal'
@@ -177,38 +178,32 @@ const Newsletter: React.FC = () => {
     } else return true
   }
 
-  const handleEditorChange = (
-    value: string,
-    type:
-      | 'info'
-      | 'title'
-      | 'content'
-      | 'question'
-      | 'link'
-      | 'image'
-      | 'subject'
-  ): void => {
+  const handleEditorChange = (value: string, type: EditorType): void => {
     setIsTouched(true)
-    if (type === 'info') {
-      setInfo(value)
-    }
-    if (type === 'title') {
-      setTitle(value)
-    }
-    if (type === 'content') {
-      setContent(value)
-    }
-    if (type === 'question') {
-      setQuestion(value)
-    }
-    if (type === 'link') {
-      setLink(value)
-    }
-    if (type === 'subject') {
-      setSubject(value)
-    }
-    if (type === 'image') {
-      setImageURL(value)
+    switch (type) {
+      case 'info':
+        setInfo(value)
+        break
+      case 'title':
+        setTitle(value)
+        break
+      case 'content':
+        setContent(value)
+        break
+      case 'question':
+        setQuestion(value)
+        break
+      case 'link':
+        setLink(value)
+        break
+      case 'subject':
+        setSubject(value)
+        break
+      case 'image':
+        setImageURL(value)
+        break
+      default:
+        break
     }
   }
   const resetFields = useCallback(() => {
diff --git a/src/components/Newsletter/Poll/Poll.tsx b/src/components/Newsletter/Poll/Poll.tsx
index 24e0d371..c8219616 100644
--- a/src/components/Newsletter/Poll/Poll.tsx
+++ b/src/components/Newsletter/Poll/Poll.tsx
@@ -1,17 +1,14 @@
 import React, { ChangeEvent } from 'react'
 import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css'
 import { convertStringToEditorState } from '../../../utils/editorStateManagement'
-import CustomEditor from '../CustomEditor'
+import CustomEditor, { EditorType } from '../CustomEditor'
 import { ContentItems } from '../Newsletter'
 import './poll.scss'
 
 interface PollProps {
   question: string
   link: string
-  handleChange: (
-    value: string,
-    type: 'info' | 'title' | 'content' | 'question' | 'link' | 'subject'
-  ) => void
+  handleChange: (value: string, type: EditorType) => void
   onSave: () => Promise<void>
   onCancel: () => void
   onDelete: (target: ContentItems) => void
@@ -45,7 +42,7 @@ const Poll: React.FC<PollProps> = ({
           <CustomEditor
             baseState={convertStringToEditorState(question)}
             handleChange={handleChange}
-            editorType="question"
+            type="question"
           />
         </div>
 
diff --git a/src/components/Popups/Popups.tsx b/src/components/Popups/Popups.tsx
index 59204192..c921d3fc 100644
--- a/src/components/Popups/Popups.tsx
+++ b/src/components/Popups/Popups.tsx
@@ -13,7 +13,9 @@ import {
 import { IPartnersInfo } from '../../models/partnersInfo.model'
 import { CustomPopupService } from '../../services/customPopup.service'
 import { PartnersInfoService } from '../../services/partnersInfo.service'
+import { convertStringToEditorState } from '../../utils/editorStateManagement'
 import Loader from '../Loader/Loader'
+import CustomEditor from '../Newsletter/CustomEditor'
 import './popups.scss'
 
 const OPTIONS: Array<Option> = [
@@ -96,13 +98,10 @@ const Popups: React.FC = () => {
     }
   }
 
-  const handlePopupChange = (
-    event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
-    field: 'title' | 'description'
-  ) => {
+  const handlePopupChange = (field: 'title' | 'description', value: string) => {
     setCustomPopup((prev) => ({
       ...prev,
-      [field]: event.target.value,
+      [field]: value,
     }))
   }
 
@@ -326,26 +325,22 @@ const Popups: React.FC = () => {
                     min={1}
                     placeholder="Titre"
                     value={customPopup.title}
-                    onChange={(event) => handlePopupChange(event, 'title')}
+                    onChange={(event) =>
+                      handlePopupChange('title', event.target.value)
+                    }
                   />
                 </div>
 
                 <div className="popupDescription">
-                  <label htmlFor="description">Description</label>
-                  <textarea
-                    name="description"
-                    id="description"
-                    placeholder="Description"
-                    rows={5}
-                    maxLength={250}
-                    value={customPopup.description}
-                    onChange={(event) =>
-                      handlePopupChange(event, 'description')
+                  <CustomEditor
+                    baseState={convertStringToEditorState(
+                      customPopup.description
+                    )}
+                    handleChange={(value) =>
+                      handlePopupChange('description', value)
                     }
+                    type="custom_popup"
                   />
-                  <p className="count">
-                    {customPopup.description.length} / 250
-                  </p>
                 </div>
 
                 <div className="popupEndDate">
diff --git a/src/components/Popups/popups.scss b/src/components/Popups/popups.scss
index 332a9617..7f93c690 100644
--- a/src/components/Popups/popups.scss
+++ b/src/components/Popups/popups.scss
@@ -77,6 +77,7 @@
   }
 
   .popupEndDate {
+    margin-top: 1rem;
     .durationInput {
       display: flex;
       gap: 1.5rem;
@@ -104,11 +105,8 @@
   }
 
   .buttons {
-    position: fixed;
-    bottom: 1rem;
     display: flex;
-    transform: translate(-25%);
-    left: 50%;
+    justify-content: center;
     gap: 1rem;
     button {
       margin: 0;
-- 
GitLab