import { Button, Dialog } from '@mui/material' import React, { useCallback, useEffect, useMemo, useState } from 'react' import { useWhoAmI } from '../../API' import { getAxiosXSRFHeader } from '../../axios.config' import { IMailSubject } from '../../models/mailSubject.model' import { IMonthlyInfo } from '../../models/monthlyInfo.model' 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 MonthlyInfo from './MonthlyInfo/MonthlyInfo' import MonthlyNews from './MonthlyNews/MonthlyNews' import Poll from './Poll/Poll' import './newsletter.scss' export type ContentItems = | 'monthlyInfo' | 'monthlyNews' | 'poll' | 'subject' | '' const Newsletter: React.FC = () => { const { data: user } = useWhoAmI() /** Display previous month until the newsletter is sent on the 3rd day of the month */ const getCurrentNewsletterDate = (): Date => { const today = new Date() const currentDay = today.getDate() const currentMonth = today.getMonth() const currentYear = today.getFullYear() return currentDay < 3 ? new Date(currentYear, currentMonth, 1) : new Date(currentYear, currentMonth + 1, 1) } const [date, setDate] = useState<Date>(getCurrentNewsletterDate()) const [info, setInfo] = useState<string>('') const [title, setTitle] = useState<string>('') const [subject, setSubject] = useState<string>('') const [imageURL, setImageURL] = useState<string>('') const [content, setContent] = useState<string>('') const [question, setQuestion] = useState<string>('') const [link, setLink] = useState<string>('') const [isTouched, setIsTouched] = useState<boolean>(false) const [refreshData, setRefreshData] = useState(false) const [isLoading, setIsLoading] = useState<boolean>(false) const [warningModal, setWarningModal] = useState<boolean>(false) const [toDelete, setToDelete] = useState<ContentItems>('') const newsletterService = useMemo(() => { return new NewsletterService() }, []) const handleSaveSubject = async (): Promise<void> => { if (user) { await newsletterService.saveMailSubject( date, subject, getAxiosXSRFHeader(user.xsrftoken) ) setIsTouched(false) } } const handleSaveMonthlyInfo = async (): Promise<void> => { if (user) { await newsletterService.saveMonthlyInfo( date, info, imageURL, getAxiosXSRFHeader(user.xsrftoken) ) setIsTouched(false) } } const handleSaveMonthlyNews = async (): Promise<void> => { if (user) { await newsletterService.saveMonthlyNews( date, title, content, getAxiosXSRFHeader(user.xsrftoken) ) setIsTouched(false) } } const handleSavePoll = async (): Promise<void> => { if (user) { await newsletterService.savePoll( date, question, link, getAxiosXSRFHeader(user.xsrftoken) ) setIsTouched(false) } } const handleCancel = useCallback(() => { setRefreshData(true) }, []) const handleDeleteMailSubject = async (): Promise<void> => { if (user) { await newsletterService.deleteMailSubject( date, getAxiosXSRFHeader(user.xsrftoken) ) setRefreshData(true) } } const handleDeleteMonthlyInfo = async (): Promise<void> => { if (user) { await newsletterService.deleteMonthlyInfo( date, getAxiosXSRFHeader(user.xsrftoken) ) setRefreshData(true) } } const handleDeleteMonthlyNews = async (): Promise<void> => { if (user) { await newsletterService.deleteMonthlyNews( date, getAxiosXSRFHeader(user.xsrftoken) ) setRefreshData(true) } } const handleDeletePoll = async (): Promise<void> => { if (user) { await newsletterService.deletePoll( date, getAxiosXSRFHeader(user.xsrftoken) ) setRefreshData(true) } } const handleOpenDeleteModal = (target: ContentItems) => { setToDelete(target) setWarningModal(true) } const handleConfirmAlert = () => { if (toDelete === 'subject') { handleDeleteMailSubject() } if (toDelete === 'monthlyInfo') { handleDeleteMonthlyInfo() } if (toDelete === 'monthlyNews') { handleDeleteMonthlyNews() } if (toDelete === 'poll') { handleDeletePoll() } setWarningModal(false) } const isEmpty = (): boolean => { if ( (info !== '' || title !== '' || content !== '' || question !== '' || imageURL !== '' || link !== '' || subject !== '') && isTouched ) { return false } else return true } const handleEditorChange = (value: string, type: EditorType): void => { setIsTouched(true) 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(() => { setSubject('') setImageURL('') setInfo('') setTitle('') setContent('') setLink('') setQuestion('') }, []) const getContentItemString = (contentItem: ContentItems) => { if (contentItem === 'monthlyInfo') return 'cette info mensuelle' if (contentItem === 'monthlyNews') return 'cette news mensuelle' if (contentItem === 'subject') return 'cet objet' return 'ce sondage' } useEffect(() => { let subscribed = true resetFields() setIsLoading(true) async function getCurrentMonthlyNews() { if (user) { const mailSubject: IMailSubject | null = await newsletterService.getSingleMailSubject( date, getAxiosXSRFHeader(user.xsrftoken) ) const monthlyInfo: IMonthlyInfo | null = await newsletterService.getSingleMonthlyInfo( date, getAxiosXSRFHeader(user.xsrftoken) ) const monthlyNews: IMonthlyNews | null = await newsletterService.getSingleMonthlyNews( date, getAxiosXSRFHeader(user.xsrftoken) ) const poll: IPoll | null = await newsletterService.getSinglePoll( date, getAxiosXSRFHeader(user.xsrftoken) ) if (mailSubject) { setSubject(mailSubject.subject) setIsTouched(false) } if (monthlyInfo) { setInfo(monthlyInfo.info) setImageURL(monthlyInfo.image) setIsTouched(false) } if (monthlyNews) { setTitle(monthlyNews.title) setContent(monthlyNews.content) setIsTouched(false) } if (poll) { setLink(poll.link) setQuestion(poll.question) setIsTouched(false) } } setIsLoading(false) } if (subscribed) { getCurrentMonthlyNews() } return () => { subscribed = false setRefreshData(false) } }, [date, user, refreshData, resetFields, newsletterService]) return ( <> <div className="header"> <h1 className="title pageTitle">Édition de la newsletter</h1> <DateSelector date={date} setDate={setDate} isEmpty={isEmpty} /> </div> {isLoading && <Loader />} {!isLoading && ( <div className="content"> <MailSubject onSave={handleSaveSubject} onCancel={handleCancel} subject={subject} handleChange={handleEditorChange} onDelete={handleOpenDeleteModal} /> <hr /> <MonthlyInfo info={info} onSave={handleSaveMonthlyInfo} onCancel={handleCancel} handleChange={handleEditorChange} onDelete={handleOpenDeleteModal} imageURL={imageURL} /> <hr /> <MonthlyNews title={title} content={content} onSave={handleSaveMonthlyNews} onCancel={handleCancel} handleChange={handleEditorChange} onDelete={handleOpenDeleteModal} /> <hr /> <Poll question={question} link={link} onSave={handleSavePoll} onCancel={handleCancel} handleChange={handleEditorChange} onDelete={handleOpenDeleteModal} /> </div> )} <Dialog open={warningModal}> <div className="modal-text"> Êtes-vous sûr de vouloir supprimer {getContentItemString(toDelete)} ? </div> <div className="buttons"> <Button variant="outlined" onClick={() => setWarningModal(false)}> Annuler </Button> <Button onClick={handleConfirmAlert}>Continuer</Button> </div> </Dialog> </> ) } export default Newsletter