Skip to content
Snippets Groups Projects
Newsletter.tsx 9.46 KiB
Newer Older
  • Learn to ignore specific revisions
  • Guilhem CARRON's avatar
    Guilhem CARRON committed
    import React, {
      useCallback,
      useContext,
      useEffect,
      useMemo,
      useState,
    } from 'react'
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    import { getAxiosXSRFHeader } from '../../axios.config'
    
    import { UserContext, UserContextProps } from '../../hooks/userContext'
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    import { IMailSubject } from '../../models/mailSubject.model'
    
    import { IMonthlyInfo } from '../../models/monthlyInfo.model'
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    import { IMonthlyNews } from '../../models/monthlyNews.model'
    
    import { IPoll } from '../../models/poll.model'
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    import { NewsletterService } from '../../services/newsletter.service'
    
    import Loader from '../Loader/Loader'
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    import DateSelector from './DateSelector/DateSelector'
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    import MailSubject from './MailSubject/mailSubject'
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    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'
      | ''
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    const Newsletter: React.FC = () => {
      // Functional rule :
    
      // Display next month after the 3rd of the current month
    
      const getCurrentNewsletterDate = (): Date => {
    
    Guilhem CARRON's avatar
    Guilhem CARRON committed
        const newsletterDate = new Date()
    
        if (newsletterDate.getDate() >= 3) {
    
          newsletterDate.setMonth(newsletterDate.getMonth() + 1)
        }
        return newsletterDate
      }
    
      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)
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
      const [isLoading, setIsLoading] = useState<boolean>(false)
      const [warningModal, setWarningModal] = useState<boolean>(false)
      const [toDelete, setToDelete] = useState<ContentItems>('')
    
      const { user }: Partial<UserContextProps> = useContext(UserContext)
    
    Guilhem CARRON's avatar
    Guilhem CARRON committed
      const newsletterService = useMemo(() => {
        return new NewsletterService()
      }, [])
    
      const handleSaveSubject = async (): Promise<void> => {
        if (user) {
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
          await newsletterService.saveMailSubject(
            date,
            subject,
            getAxiosXSRFHeader(user.xsrftoken)
          )
    
          setIsTouched(false)
        }
      }
    
    
      const handleSaveMonthlyInfo = async (): Promise<void> => {
        if (user) {
          await newsletterService.saveMonthlyInfo(
            date,
            info,
            imageURL,
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
            getAxiosXSRFHeader(user.xsrftoken)
    
          )
          setIsTouched(false)
        }
      }
    
      const handleSaveMonthlyNews = async (): Promise<void> => {
        if (user) {
          await newsletterService.saveMonthlyNews(
            date,
            title,
            content,
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
            getAxiosXSRFHeader(user.xsrftoken)
    
          )
          setIsTouched(false)
        }
      }
      const handleSavePoll = async (): Promise<void> => {
        if (user) {
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
          await newsletterService.savePoll(
            date,
            question,
            link,
            getAxiosXSRFHeader(user.xsrftoken)
          )
    
          setIsTouched(false)
        }
      }
      const handleCancel = useCallback(() => {
        setRefreshData(true)
      }, [])
    
    
      const handleDeleteMailSubject = async (): Promise<void> => {
        if (user) {
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
          await newsletterService.deleteMailSubject(
            date,
            getAxiosXSRFHeader(user.xsrftoken)
          )
    
          setRefreshData(true)
        }
      }
    
      const handleDeleteMonthlyInfo = async (): Promise<void> => {
        if (user) {
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
          await newsletterService.deleteMonthlyInfo(
            date,
            getAxiosXSRFHeader(user.xsrftoken)
          )
    
          setRefreshData(true)
        }
      }
      const handleDeleteMonthlyNews = async (): Promise<void> => {
        if (user) {
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
          await newsletterService.deleteMonthlyNews(
            date,
            getAxiosXSRFHeader(user.xsrftoken)
          )
    
          setRefreshData(true)
        }
      }
      const handleDeletePoll = async (): Promise<void> => {
        if (user) {
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
          await newsletterService.deletePoll(
            date,
            getAxiosXSRFHeader(user.xsrftoken)
          )
    
          setRefreshData(true)
        }
      }
      const handleOpenDeleteModal = (target: ContentItems) => {
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
        setToDelete(target)
        setWarningModal(true)
    
      }
      const handleConfirmAlert = () => {
    
        if (toDelete === 'subject') {
          handleDeleteMailSubject()
        }
    
        if (toDelete === 'monthlyInfo') {
          handleDeleteMonthlyInfo()
        }
        if (toDelete === 'monthlyNews') {
          handleDeleteMonthlyNews()
        }
        if (toDelete === 'poll') {
          handleDeletePoll()
        }
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
        setWarningModal(false)
    
      }
    
      const isEmpty = (): boolean => {
        if (
          (info !== '' ||
            title !== '' ||
            content !== '' ||
            question !== '' ||
            imageURL !== '' ||
    
            link !== '' ||
            subject !== '') &&
    
          isTouched
        ) {
          return false
        } else return true
      }
    
    
      const handleEditorChange = (
        value: string,
        type:
          | 'info'
          | 'title'
          | 'content'
          | 'question'
          | 'link'
          | 'image'
          | 'subject'
      ): 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)
        }
      }
    
      const resetFields = useCallback(() => {
    
        setSubject('')
    
        setImageURL('')
        setInfo('')
        setTitle('')
        setContent('')
        setLink('')
        setQuestion('')
      }, [])
    
    
    Guilhem CARRON's avatar
    Guilhem CARRON committed
      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()
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
        setIsLoading(true)
    
        async function getCurrentMonthlyNews() {
          if (user) {
    
            const mailSubject: IMailSubject | null =
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
              await newsletterService.getSingleMailSubject(
                date,
                getAxiosXSRFHeader(user.xsrftoken)
              )
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
            const monthlyInfo: IMonthlyInfo | null =
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
              await newsletterService.getSingleMonthlyInfo(
                date,
                getAxiosXSRFHeader(user.xsrftoken)
              )
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
            const monthlyNews: IMonthlyNews | null =
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
              await newsletterService.getSingleMonthlyNews(
                date,
                getAxiosXSRFHeader(user.xsrftoken)
              )
    
            const poll: IPoll | null = await newsletterService.getSinglePoll(
              date,
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
              getAxiosXSRFHeader(user.xsrftoken)
    
            if (mailSubject) {
              setSubject(mailSubject.subject)
              setIsTouched(false)
            }
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
            if (monthlyInfo) {
              setInfo(monthlyInfo.info)
              setImageURL(monthlyInfo.image)
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
            if (monthlyNews) {
              setTitle(monthlyNews.title)
              setContent(monthlyNews.content)
    
              setIsTouched(false)
            }
            if (poll) {
              setLink(poll.link)
              setQuestion(poll.question)
              setIsTouched(false)
            }
          }
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
          setIsLoading(false)
    
        }
        if (subscribed) {
          getCurrentMonthlyNews()
        }
        return () => {
          subscribed = false
          setRefreshData(false)
        }
    
    Guilhem CARRON's avatar
    Guilhem CARRON committed
      }, [date, user, refreshData, resetFields, newsletterService])
    
    
      return (
        <>
          <div className="header">
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
            <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">
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
                  Êtes-vous sûr de vouloir supprimer{' '}
    
                  {getContentItemString(toDelete)}&nbsp;?
    
                </div>
                <div className="buttons">
                  <button
                    className="btnCancel"
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
                    onClick={() => setWarningModal(false)}
    
                  >
                    Annuler
                  </button>
                  <button className="btnValid" onClick={handleConfirmAlert}>
                    Continuer
                  </button>
                </div>
              </>
            </Modal>
          )}
        </>
      )
    }
    
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    export default Newsletter