diff --git a/src/package.json b/src/package.json index a505d086..53fb5bca 100644 --- a/src/package.json +++ b/src/package.json @@ -1,28 +1,29 @@ { - "private": true, - "scripts": { - "dev": "npm run development", - "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", - "watch": "npm run development -- --watch", - "watch-poll": "npm run watch -- --watch-poll", - "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js", - "prod": "npm run production", - "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" - }, - "devDependencies": { - "axios": "^0.19", - "bootstrap": "^4.3.1", - "cross-env": "^5.1", - "jquery": "^3.4.1", - "laravel-mix": "^4.0.7", - "lodash": "^4.17.13", - "popper.js": "^1.12", - "resolve-url-loader": "^2.3.1", - "sass": "^1.15.2", - "sass-loader": "^7.1.0", - "vue": "^2.5.17", - "vue-router": "^3.1.3", - "vue-template-compiler": "^2.6.10", - "vuex": "^3.1.1" - } + "private": true, + "scripts": { + "dev": "npm run development", + "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", + "watch": "npm run development -- --watch", + "watch-poll": "npm run watch -- --watch-poll", + "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js", + "prod": "npm run production", + "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" + }, + "devDependencies": { + "axios": "^0.19", + "bootstrap": "^4.3.1", + "cross-env": "^5.1", + "jquery": "^3.4.1", + "laravel-mix": "^4.0.7", + "lodash": "^4.17.13", + "popper.js": "^1.12", + "resolve-url-loader": "^2.3.1", + "sass": "^1.15.2", + "sass-loader": "^7.1.0", + "vue": "^2.5.17", + "vue-router": "^3.1.3", + "vue-template-compiler": "^2.6.10", + "vuex": "^3.1.1", + "@deveodk/vue-toastr": "^1.1.0" + } } diff --git a/src/resources/js/app.js b/src/resources/js/app.js index ba5998c8..ed9013b0 100644 --- a/src/resources/js/app.js +++ b/src/resources/js/app.js @@ -1,18 +1,81 @@ /** * First we will load all of this project's JavaScript dependencies which * includes Vue and other libraries. It is a great starting point when * building robust, powerful web applications using Vue and Laravel. */ -require('./bootstrap'); +require('./bootstrap') -window.Vue = require('vue'); +window.Vue = require('vue') -import router from '../vue/js/routes.js'; +import router from '../vue/js/routes.js' import AppComponent from '../vue/components/App' const app = new Vue({ + el: '#app', components: { AppComponent }, - router -}).$mount('#app'); + router, + methods: { + clearFormValidation: form => { + $(form).find('.is-invalid').removeClass('is-invalid') + $(form).find('.invalid-feedback').remove() + } + }, + mounted() { + this.$root.$on('clearFormValidation', (form) => { + this.clearFormValidation(form) + }) + } +}) + +import VueToastr from '@deveodk/vue-toastr' +// You need a specific loader for CSS files like https://github.com/webpack/css-loader +// If you would like custom styling of the toastr the css file can be replaced +import '@deveodk/vue-toastr/dist/@deveodk/vue-toastr.css' + +Vue.use(VueToastr, { + defaultPosition: 'toast-bottom-right', + defaultTimeout: 50000 +}) + +// Add a response interceptor for general/validation error handler +window.axios.interceptors.response.use(response => { + // Do nothing + return response + }, error => { + console.log(error.response) + + var error_msg + + if (error.response && error.response.status == 422) { + error_msg = "Form validation error" + + $.each(error.response.data.errors || {}, (idx, msg) => { + $('form').each((i, form) => { + const input_name = ($(form).data('validation-prefix') || '') + idx + const input = $('#' + input_name) + + if (input.length) { + input.addClass('is-invalid') + .parent().append($('
').text(msg.join('
'))) + + return false + } + }); + }) + + $('form .is-invalid').first().focus() + } + else if (error.response && error.response.data) { + error_msg = error.response.data.message + } + else { + error_msg = error.request ? error.request.statusText : error.message + } + + app.$toastr('error', error_msg || "Server Error", 'Error') + + // Pass the error as-is + return Promise.reject(error) + }); diff --git a/src/resources/js/bootstrap.js b/src/resources/js/bootstrap.js index 8eaba1b9..a1b0631d 100644 --- a/src/resources/js/bootstrap.js +++ b/src/resources/js/bootstrap.js @@ -1,41 +1,41 @@ -window._ = require('lodash'); +window._ = require('lodash') /** * We'll load jQuery and the Bootstrap jQuery plugin which provides support * for JavaScript based Bootstrap features such as modals and tabs. This * code may be modified to fit the specific needs of your application. */ try { - window.Popper = require('popper.js').default; - window.$ = window.jQuery = require('jquery'); + window.Popper = require('popper.js').default + window.$ = window.jQuery = require('jquery') - require('bootstrap'); + require('bootstrap') } catch (e) {} /** * We'll load the axios HTTP library which allows us to easily issue requests * to our Laravel back-end. This library automatically handles sending the * CSRF token as a header based on the value of the "XSRF" token cookie. */ -window.axios = require('axios'); +window.axios = require('axios') -window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; +window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest' /** * Echo exposes an expressive API for subscribing to channels and listening * for events that are broadcast by Laravel. Echo and event broadcasting * allows your team to easily build robust real-time web applications. */ // import Echo from 'laravel-echo'; // window.Pusher = require('pusher-js'); // window.Echo = new Echo({ // broadcaster: 'pusher', // key: process.env.MIX_PUSHER_APP_KEY, // cluster: process.env.MIX_PUSHER_APP_CLUSTER, // encrypted: true // }); diff --git a/src/resources/sass/app.scss b/src/resources/sass/app.scss index fa9d5c91..a6f04262 100644 --- a/src/resources/sass/app.scss +++ b/src/resources/sass/app.scss @@ -1,7 +1,13 @@ // Fonts // Variables @import 'variables'; // Bootstrap @import '~bootstrap/scss/bootstrap'; + + +// Fixes Toastr incompatibility with Bootstrap +.toast-container > .toast { + opacity: 1; +} diff --git a/src/resources/vue/components/App.vue b/src/resources/vue/components/App.vue index fd3c6864..f9cc0a3b 100644 --- a/src/resources/vue/components/App.vue +++ b/src/resources/vue/components/App.vue @@ -1,31 +1,27 @@ diff --git a/src/resources/vue/components/Dashboard.vue b/src/resources/vue/components/Dashboard.vue index 5598269f..7408b890 100644 --- a/src/resources/vue/components/Dashboard.vue +++ b/src/resources/vue/components/Dashboard.vue @@ -1,43 +1,41 @@ diff --git a/src/resources/vue/components/Signup.vue b/src/resources/vue/components/Signup.vue index 00ba3ff8..7facaf34 100644 --- a/src/resources/vue/components/Signup.vue +++ b/src/resources/vue/components/Signup.vue @@ -1,158 +1,158 @@