1- import React , { useEffect , useState } from 'react' ;
1+ import React , { useEffect , useRef , useState } from 'react' ;
22import {
33 Button ,
44 Center ,
@@ -32,10 +32,7 @@ import {
3232} from '@chakra-ui/react' ;
3333import { FaPlus , FaAngleDown , FaAngleUp } from 'react-icons/fa' ;
3434import { useClient } from 'urql' ;
35- import { Editor } from 'react-draft-wysiwyg' ;
36- import { EditorState , convertToRaw , Modifier } from 'draft-js' ;
37- import draftToHtml from 'draftjs-to-html' ;
38- import { stateFromHTML } from 'draft-js-import-html' ;
35+ import EmailEditor from 'react-email-editor' ;
3936import {
4037 UpdateModalViews ,
4138 EmailTemplateInputDataFields ,
@@ -51,6 +48,7 @@ interface selectedEmailTemplateDataTypes {
5148 [ EmailTemplateInputDataFields . SUBJECT ] : string ;
5249 [ EmailTemplateInputDataFields . CREATED_AT ] : number ;
5350 [ EmailTemplateInputDataFields . TEMPLATE ] : string ;
51+ [ EmailTemplateInputDataFields . DESIGN ] : string ;
5452}
5553
5654interface UpdateEmailTemplateInputPropTypes {
@@ -90,11 +88,9 @@ const UpdateEmailTemplate = ({
9088} : UpdateEmailTemplateInputPropTypes ) => {
9189 const client = useClient ( ) ;
9290 const toast = useToast ( ) ;
91+ const emailEditorRef = useRef ( null ) ;
9392 const { isOpen, onOpen, onClose } = useDisclosure ( ) ;
9493 const [ loading , setLoading ] = useState < boolean > ( false ) ;
95- const [ editorState , setEditorState ] = React . useState < EditorState > (
96- EditorState . createEmpty ( )
97- ) ;
9894 const [ templateVariables , setTemplateVariables ] = useState <
9995 templateVariableDataTypes [ ]
10096 > ( [ ] ) ;
@@ -104,12 +100,23 @@ const UpdateEmailTemplate = ({
104100 const [ validator , setValidator ] = useState < validatorDataType > ( {
105101 ...initTemplateValidatorData ,
106102 } ) ;
107- const onEditorStateChange = ( editorState : EditorState ) => {
108- setEditorState ( editorState ) ;
109- } ;
110103 const [ isDynamicVariableInfoOpen , setIsDynamicVariableInfoOpen ] =
111104 useState < boolean > ( false ) ;
112105
106+ const onReady = ( ) => {
107+ if ( selectedTemplate ) {
108+ const { design } = selectedTemplate ;
109+ try {
110+ const designData = JSON . parse ( design ) ;
111+ // @ts -ignore
112+ emailEditorRef . current . editor . loadDesign ( designData ) ;
113+ } catch ( error ) {
114+ console . error ( error ) ;
115+ onClose ( ) ;
116+ }
117+ }
118+ } ;
119+
113120 const inputChangehandler = ( inputType : string , value : any ) => {
114121 if ( inputType !== EmailTemplateInputDataFields . EVENT_NAME ) {
115122 setValidator ( {
@@ -121,14 +128,8 @@ const UpdateEmailTemplate = ({
121128 } ;
122129
123130 const validateData = ( ) => {
124- const rawData : string = draftToHtml (
125- convertToRaw ( editorState . getCurrentContent ( ) )
126- ) . trim ( ) ;
127131 return (
128132 ! loading &&
129- rawData &&
130- rawData !== '<p></p>' &&
131- rawData !== '<h1></h1>' &&
132133 templateData [ EmailTemplateInputDataFields . EVENT_NAME ] . length > 0 &&
133134 templateData [ EmailTemplateInputDataFields . SUBJECT ] . length > 0 &&
134135 validator [ EmailTemplateInputDataFields . SUBJECT ]
@@ -138,69 +139,72 @@ const UpdateEmailTemplate = ({
138139 const saveData = async ( ) => {
139140 if ( ! validateData ( ) ) return ;
140141 setLoading ( true ) ;
141- const params = {
142- [ EmailTemplateInputDataFields . EVENT_NAME ] :
143- templateData [ EmailTemplateInputDataFields . EVENT_NAME ] ,
144- [ EmailTemplateInputDataFields . SUBJECT ] :
145- templateData [ EmailTemplateInputDataFields . SUBJECT ] ,
146- [ EmailTemplateInputDataFields . TEMPLATE ] : draftToHtml (
147- convertToRaw ( editorState . getCurrentContent ( ) )
148- ) . trim ( ) ,
149- } ;
150- let res : any = { } ;
151- if (
152- view === UpdateModalViews . Edit &&
153- selectedTemplate ?. [ EmailTemplateInputDataFields . ID ]
154- ) {
155- res = await client
156- . mutation ( EditEmailTemplate , {
157- params : {
158- ...params ,
159- id : selectedTemplate [ EmailTemplateInputDataFields . ID ] ,
160- } ,
161- } )
162- . toPromise ( ) ;
163- } else {
164- res = await client . mutation ( AddEmailTemplate , { params } ) . toPromise ( ) ;
165- }
166- setLoading ( false ) ;
167- if ( res . error ) {
168- toast ( {
169- title : capitalizeFirstLetter ( res . error . message ) ,
170- isClosable : true ,
171- status : 'error' ,
172- position : 'bottom-right' ,
173- } ) ;
174- } else if (
175- res . data ?. _add_email_template ||
176- res . data ?. _update_email_template
177- ) {
178- toast ( {
179- title : capitalizeFirstLetter (
180- res . data ?. _add_email_template ?. message ||
181- res . data ?. _update_email_template ?. message
182- ) ,
183- isClosable : true ,
184- status : 'success' ,
185- position : 'bottom-right' ,
186- } ) ;
187- setTemplateData ( {
188- ...initTemplateData ,
189- } ) ;
190- setValidator ( { ...initTemplateValidatorData } ) ;
191- fetchEmailTemplatesData ( ) ;
192- }
193- view === UpdateModalViews . ADD && onClose ( ) ;
142+ // @ts -ignore
143+ return await emailEditorRef . current . editor . exportHtml ( async ( data ) => {
144+ const { design, html } = data ;
145+ if ( ! html || ! design ) {
146+ setLoading ( false ) ;
147+ return ;
148+ }
149+ const params = {
150+ [ EmailTemplateInputDataFields . EVENT_NAME ] :
151+ templateData [ EmailTemplateInputDataFields . EVENT_NAME ] ,
152+ [ EmailTemplateInputDataFields . SUBJECT ] :
153+ templateData [ EmailTemplateInputDataFields . SUBJECT ] ,
154+ [ EmailTemplateInputDataFields . TEMPLATE ] : html . trim ( ) ,
155+ [ EmailTemplateInputDataFields . DESIGN ] : JSON . stringify ( design ) ,
156+ } ;
157+ let res : any = { } ;
158+ if (
159+ view === UpdateModalViews . Edit &&
160+ selectedTemplate ?. [ EmailTemplateInputDataFields . ID ]
161+ ) {
162+ res = await client
163+ . mutation ( EditEmailTemplate , {
164+ params : {
165+ ...params ,
166+ id : selectedTemplate [ EmailTemplateInputDataFields . ID ] ,
167+ } ,
168+ } )
169+ . toPromise ( ) ;
170+ } else {
171+ res = await client . mutation ( AddEmailTemplate , { params } ) . toPromise ( ) ;
172+ }
173+ setLoading ( false ) ;
174+ if ( res . error ) {
175+ toast ( {
176+ title : capitalizeFirstLetter ( res . error . message ) ,
177+ isClosable : true ,
178+ status : 'error' ,
179+ position : 'bottom-right' ,
180+ } ) ;
181+ } else if (
182+ res . data ?. _add_email_template ||
183+ res . data ?. _update_email_template
184+ ) {
185+ toast ( {
186+ title : capitalizeFirstLetter (
187+ res . data ?. _add_email_template ?. message ||
188+ res . data ?. _update_email_template ?. message
189+ ) ,
190+ isClosable : true ,
191+ status : 'success' ,
192+ position : 'bottom-right' ,
193+ } ) ;
194+ setTemplateData ( {
195+ ...initTemplateData ,
196+ } ) ;
197+ setValidator ( { ...initTemplateValidatorData } ) ;
198+ fetchEmailTemplatesData ( ) ;
199+ }
200+ view === UpdateModalViews . ADD && onClose ( ) ;
201+ } ) ;
194202 } ;
195203 const resetData = ( ) => {
196204 if ( selectedTemplate ) {
197205 setTemplateData ( selectedTemplate ) ;
198- setEditorState (
199- EditorState . createWithContent ( stateFromHTML ( selectedTemplate . template ) )
200- ) ;
201206 } else {
202207 setTemplateData ( { ...initTemplateData } ) ;
203- setEditorState ( EditorState . createEmpty ( ) ) ;
204208 }
205209 } ;
206210 useEffect ( ( ) => {
@@ -210,9 +214,8 @@ const UpdateEmailTemplate = ({
210214 selectedTemplate &&
211215 Object . keys ( selectedTemplate || { } ) . length
212216 ) {
213- const { id, created_at, template, ...rest } = selectedTemplate ;
217+ const { id, created_at, template, design , ...rest } = selectedTemplate ;
214218 setTemplateData ( rest ) ;
215- setEditorState ( EditorState . createWithContent ( stateFromHTML ( template ) ) ) ;
216219 }
217220 } , [ isOpen ] ) ;
218221 useEffect ( ( ) => {
@@ -263,7 +266,7 @@ const UpdateEmailTemplate = ({
263266 resetData ( ) ;
264267 onClose ( ) ;
265268 } }
266- size = "3xl "
269+ size = "6xl "
267270 >
268271 < ModalOverlay />
269272 < ModalContent >
@@ -287,7 +290,7 @@ const UpdateEmailTemplate = ({
287290 setIsDynamicVariableInfoOpen ( ! isDynamicVariableInfoOpen )
288291 }
289292 borderRadius = "5"
290- marginY = { 5 }
293+ marginBottom = { 5 }
291294 cursor = "pointer"
292295 fontSize = "sm"
293296 >
@@ -382,7 +385,7 @@ const UpdateEmailTemplate = ({
382385 width = "100%"
383386 justifyContent = "start"
384387 alignItems = "center"
385- marginBottom = "5 %"
388+ marginBottom = "2 %"
386389 >
387390 < Flex flex = "1" > Subject</ Flex >
388391 < Flex flex = "3" >
@@ -407,41 +410,21 @@ const UpdateEmailTemplate = ({
407410 </ Flex >
408411 < Flex
409412 width = "100%"
410- justifyContent = "space-between "
413+ justifyContent = "flex-start "
411414 alignItems = "center"
412415 marginBottom = "2%"
413416 >
414- < Flex > Template Body</ Flex >
415- < Text
416- style = { {
417- fontSize : 14 ,
418- } }
419- color = "gray.400"
420- > { `To select dynamic variables open curly braces "{"` } </ Text >
417+ Template Body
418+ </ Flex >
419+ < Flex
420+ width = "100%"
421+ justifyContent = "flex-start"
422+ alignItems = "center"
423+ border = "1px solid"
424+ borderColor = "gray.200"
425+ >
426+ < EmailEditor ref = { emailEditorRef } onReady = { onReady } />
421427 </ Flex >
422- < Editor
423- editorState = { editorState }
424- onEditorStateChange = { onEditorStateChange }
425- editorStyle = { {
426- border : '1px solid #d9d9d9' ,
427- borderRadius : '5px' ,
428- marginTop : '2%' ,
429- height : '30vh' ,
430- padding : 10 ,
431- } }
432- mention = { {
433- separator : ' ' ,
434- trigger : '{' ,
435- suggestions : templateVariables ,
436- } }
437- />
438- < Alert status = "info" marginY = { 5 } borderRadius = { 5 } >
439- < AlertIcon />
440- < Box fontSize = "sm" >
441- < b > Note:</ b > In order to use dynamic variables with link and
442- images you can put them as part of URL in editor section.
443- </ Box >
444- </ Alert >
445428 </ Flex >
446429 </ ModalBody >
447430 < ModalFooter >
0 commit comments