Это внешний интерфейс с использованием vue2, который охватывает эту статью https://medium.com/@toluarejibadey/how-to-build-an-email-scheduler-with-express-vue-nodemailer-node-cron-and- mongodb-c9e99e1b10e1

Шаг № 1: Перейдите в свой cmd и введите

vue create ui

установите vue 2 после завершения установки внутри вашей папки vue install

npm install vuelidate vue-notification axios bootstrap

добавьте это в свой файл main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'

import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap'
import Vuelidate from "vuelidate";
import Notifications from 'vue-notification'
import 'jquery/src/jquery.js'
import 'bootstrap/dist/js/bootstrap.min.js'
import VueSweetalert2 from 'vue-sweetalert2';
import 'sweetalert2/dist/sweetalert2.min.css';

Vue.config.productionTip = false

Vue.use(Notifications)


Vue.use(Vuelidate);
Vue.use(VueSweetalert2);
new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

Шаг № 2: Добавьте это в свой файл vue

здесь мы просто получаем данные из формы и отправляем их в серверную часть

<template>

  <body>
    <div class="container">
      <div class="row justify-content-center">

        <div class="col-xs-12 col-sm-12 col-md-8 col-lg-6  column col-sm-offset-0 col-md-offset-2 col-lg-offset-3">
          <h3 class="justify-content-center">Schedule email</h3>
          <hr />
          <form class="form-horizontal">
            <div>
              <label>
                to
              </label>
              <input
                type="text"
                :class="{ error: $v.to.$error }"
                @input="$v.to.$touch()"
                class="form-control"
                placeholder="[email protected]"
                v-model.trim="to"
              >
              <div v-if="$v.to.$dirty">
                <p
                  class="error-message"
                  v-if="!$v.to.email"
                >
                  Please enter a valid email address.
                </p>
                <p
                  class="error-message"
                  v-if="!$v.to.required"
                >
                  Email must not be empty.
                </p>
              </div>
            </div>
            <div>
              <label>
                subject
              </label>
              <input
                type="text"
                :class="{ error: $v.subject.$error }"
                @input="$v.subject.$touch()"
                class="form-control"
                placeholder="enter subject"
                v-model.trim="subject"
              >
              <div v-if="$v.subject.$dirty">

                <p
                  class="error-message"
                  v-if="!$v.subject.required"
                >
                  field is required
                </p>
              </div>
            </div>
            <div class="row">
              <div class="col-md-6">
                <div>
                  <label>
                    minute
                  </label>
                  <input
                    type="text"
                    :class="{ error: $v.minute.$error }"
                    @input="$v.minute.$touch()"
                    class="form-control"
                    placeholder="0-59"
                    v-model.trim="minute"
                  >
                  <div v-if="$v.minute.$dirty">

                    <p
                      class="error-message"
                      v-if="!$v.minute.required"
                    >
                      field is required
                    </p>
                  </div>
                </div>
              </div>
              <div class="col-md-6">
                <div>

                  <label>
                    hour
                  </label>
                  <input
                    type="text"
                    :class="{ error: $v. hour.$error }"
                    @input="$v. hour.$touch()"
                    class="form-control"
                    placeholder="0-23"
                    v-model.trim=" hour"
                  >
                  <div v-if="$v. hour.$dirty">

                    <p
                      class="error-message"
                      v-if="!$v. hour.required"
                    >
                      field is required.
                    </p>
                  </div>
                </div>
              </div>
            </div>
            <div class="row">
              <div class="col-md-6">
                <div>
                  <label>
                    week
                  </label>
                  <select
                    name
                    class="form-control"
                    id
                    :class="{ error: $v. week.$error }"
                    @input="$v. week.$touch()"
                    placeholder="Sunday"
                    v-model.trim="week"
                  >

                    <option value="Monday">Monday</option>
                    <option value="Tuesday">Tuesday</option>
                    <option value="Wednesday">Wednesday</option>
                    <option value="Thursday">Thursday</option>
                    <option value="Friday">Friday</option>
                    <option value="Saturday">Saturday</option>
                    <option value="Sunday">Sunday</option>

                  </select>

                  <div v-if="$v. week.$dirty">

                    <p
                      class="error-message"
                      v-if="!$v. week.required"
                    >
                      field must not be empty.
                    </p>
                  </div>
                </div>
              </div>
              <div class="col-md-6">
                <div>
                  <label>
                    month
                  </label>
                  <select
                    name
                    class="form-control"
                    id
                    :class="{ error: $v. month.$error }"
                    @input="$v. month.$touch()"
                    placeholder="Month"
                    v-model.trim=" month"
                  >

                    <option value="January">January</option>
                    <option value="February">February</option>
                    <option value="March">March</option>
                    <option value="April">April</option>
                    <option value="May">May</option>
                    <option value="June">June</option>
                    <option value="July">July</option>
                    <option value="August">August</option>
                    <option value="September">September</option>
                    <option value="Ocotber">October</option>
                    <option value="November">November</option>
                    <option value="December">December</option>

                  </select>

                  <div v-if="$v. month.$dirty">

                    <p
                      class="error-message"
                      v-if="!$v. month.required"
                    >
                      field must not be empty.
                    </p>
                  </div>
                </div>
              </div>
            </div>

            <div>
              <label>
                day
              </label>
              <input
                type="text"
                :class="{ error: $v. day.$error }"
                @input="$v. day.$touch()"
                class="form-control"
                placeholder="0-31"
                v-model.trim=" day"
              >
              <div v-if="$v. day.$dirty">

                <p
                  class="error-message"
                  v-if="!$v. day.required"
                >
                  field must not be empty.
                </p>
              </div>
            </div>
            <div>
              <label>
                message
              </label>
              <textarea
                type="text"
                rows="5"
                :class="{ error: $v.html.$error }"
                @input="$v.html.$touch()"
                class="form-control"
                id="textarea"
                name="textarea"
                placeholder="enter message"
                v-model.trim="html"
              >
        </textarea>
              <div v-if="$v.html.$dirty">

                <p
                  class="error-message"
                  v-if="!$v.html.required"
                >
                  field must not be empty.
                </p>
              </div>
            </div>
            <div>
              <label>
                Attachment
              </label>
              <input
                type="file"
                @change="onFileSelected"
                name="file"
                class="form-control"
                ref="files"
              >

            </div>
            <br>
            <div class="d-flex  justify-content-center">
              <button
                :disabled="$v.$invalid"
                type="submit"
                id="form-submit"
                class="btn btn-info btn-sm"
                @click.prevent="send"
              >Submit</button>
            </div>
            
          </form>
        </div>
      </div>
    </div>

  </body>

</template>  

вот тег скрипта и стиль

<script>
import axios from "axios";
import { required, minLength, between, email } from "vuelidate/lib/validators";

export default {
  name: "App",
  components: {},
  data() {
    return {
      message: "",
      to: "",
      subject: "",
      // second: "",
      minute: "",
      hour: "",
      week: "",
      month: "",
      day: "",
      html: "",
      file: null
    };
  },
// validation for forms
  validations: {
    to: {
      required,
      email
    },
    html: {
      required
    },
    minute: {
      required
    },
    day: {
      required
    },
    month: {
      required
    },
    week: {
      required
    },
    hour: {
      required
    },

    subject: {
      required
    }
  },

  methods: {
// get the uploaded file
    onFileSelected(event) {
      this.selectedFile = event.target.files[0];
      this.fileName = event.target.files[0].name;
    },
// we us form data cause we are sending attachment
    async send() {
      let data = new FormData();
      data.append("to", this.to);
      data.append("file", this.selectedFile, this.selectedFile.name);
      data.append("html", this.html);
      data.append("minute", this.minute);
      data.append("hour", this.hour);
      data.append("month", this.month);
      data.append("day", this.day);
      data.append("week", this.week);

      data.append("subject", this.subject);

      const response = await axios.post(
        "http://localhost:3000/api/crons",
        data
      );
      this.$notify(`email sent`);
    }
  }
};
</script>
<style>
input:focus {
  outline: none;
}
.error {
  border: 1px solid red;
}
.error-message {
  color: red;
}
</style>