Let’s add a new thing to the admin panel: a composer view.

We just add it on top of the emails list, without adding an additional view.

I am going to use the simplest editor I can find. I found pell, which markets itself as the smallest and simplest editor for the web.

Looks like what I’m looking for! We don’t want to overcomplicate the frontend, after all it’s a Node course.

We just need to add this to our admin.pug file:

html
  head
    link(rel='stylesheet', href='https://unpkg.com/pell/dist/pell.min.css')

  body
    main
      h1 Compose email

      div#editor.pell


	  	//- the existing content goes here


    	//- (at the end)
    	script(src='https://unpkg.com/pell')
    	script(src='/editor.js')

Now create a public/editor.js file with this content:

document.addEventListener("DOMContentLoaded", () => {
  pell.init({
    element: document.getElementById('editor'),
    onChange: html => document.emailHtml = html,
    defaultParagraphSeparator: 'p',
    styleWithCSS: true,
    actions: [
      'bold',
      'underline',
      {
        name: 'italic',
        result: () => pell.exec('italic')
      },
      {
        name: 'link',
        result: () => {
          const url = window.prompt('Enter the link URL')
          if (url) pell.exec('createLink', url)
        }
      }
    ]
  })
})

You don’t really need to understand what’s going on here, since it’s frontend code, but basically we initialize the editor with some buttons. It’s a very minimal setup, which gives us this nice simple editor view:

Let’s create a button that will send the email to the list. Add:

button#send Send email
hr

after the editor in views/admin.pug.

Then add this CSS to public/style.css:

/* make the text in the editor align left */
.pell-content {
  text-align: left;
}

button#send {
  margin-top: 15px;
}

You should see this:

Now when the button is clicked nothing happens, because it’s not put in any form.

We can listen for clicks in the editor.js file. In there, we’ll put an Axios call to our backend, passing the email text.

Notice I didn’t put a subject field. You will add it yourself in one of the project challenges later.

When we change the content, we store the content of the editor in the document.emailHtml global variable. Not ideal, but works (again, it’s not a frontend development course).

We can reference it in our click event listener:

document.querySelector('button#send').addEventListener('click', (event) => {
  console.log(document.emailHtml)
})

Now, we use Axios. Add

script(src='https://unpkg.com/axios/dist/axios.min.js')

at the end of views/admin.pug.

We add the Axios call to the click event listener:

axios.post('/send', {
  content: document.emailHtml
}).then(() => {
  document.querySelector('button#send').innerText = 'Sent!'
  document.querySelector('button#send').disabled = true
}).catch(err => {
  console.error(err)
  alert('An error occurred! Check the console log')
})

Let’s switch to server.js and create a /send POST endpoint.

app.post('/send', (req, res) => {
  const content = req.body.content
  console.log(content)
  res.end()
})

Now when you press the send button, the server should log the email content.

See the app at the current point on Glitch :・゚✧


Go to the next lesson