import React, { useCallback, useContext, useEffect, useMemo, useState, } from 'react' import { getAxiosXSRFHeader } from '../../axios.config' import { UserContext, UserContextProps } from '../../hooks/userContext' 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 Modal from './Modal/Modal' 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 = () => { /** * 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 { user }: Partial<UserContextProps> = useContext(UserContext) 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"> <p className="title pageTitle">Édition de la newsletter</p> <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} ></MailSubject> <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> )} {warningModal && ( <Modal> <> <div className="modal-text"> Êtes-vous sûr de vouloir supprimer{' '} {getContentItemString(toDelete)} ? </div> <div className="buttons"> <button className="btnCancel" onClick={() => setWarningModal(false)} > Annuler </button> <button className="btnValid" onClick={handleConfirmAlert}> Continuer </button> </div> </> </Modal> )} </> ) } export default Newsletter