Это внешний интерфейс с использованием 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>