Sfoglia il codice sorgente

Add loading button

sbkwgh 8 anni fa
parent
commit
323af47f99
3 ha cambiato i file con 116 aggiunte e 9 eliminazioni
  1. 20 5
      src/App.vue
  2. 57 0
      src/components/LoadingButton.vue
  3. 39 4
      src/components/routes/Start.vue

+ 20 - 5
src/App.vue

@@ -36,9 +36,9 @@
 						width='100%'
 					>
 					</fancy-input>
-					<button class='button button--green' @click='createAccount'>
+					<loading-button class='button--green' :loading='signup.loading' @click='createAccount'>
 						Sign up
-					</button>
+					</loading-button>
 					<button class='button' @click='closeAccountModal'>
 						Cancel
 					</button>
@@ -62,9 +62,9 @@
 						width='100%'
 					>
 					</fancy-input>
-					<button class='button button--green' @click='doLogin'>
+					<loading-button class='button button--green' :loading='login.loading' @click='doLogin'>
 						Log in
-					</button>
+					</loading-button>
 					<button class='button' @click='closeAccountModal'>
 						Cancel
 					</button>
@@ -103,6 +103,7 @@
 	import ModalWindow from './components/ModalWindow'
 	import TabView from './components/TabView'
 	import FancyInput from './components/FancyInput'
+	import LoadingButton from './components/LoadingButton'
 
 	import mapGetters from 'vuex'
 
@@ -113,7 +114,8 @@
 		components: {
 			ModalWindow,
 			TabView,
-			FancyInput
+			FancyInput,
+			LoadingButton
 		},
 		data () {
 			return {
@@ -122,6 +124,8 @@
 					password: '',
 					confirmPassword: '',
 
+					loading: false,
+
 					errors: {
 						username: '',
 						password: '',
@@ -132,6 +136,8 @@
 					username: '',
 					password: '',
 
+					loading: false,
+
 					errors: {
 						username: '',
 						password: ''
@@ -206,13 +212,18 @@
 				if(this.signup.password !== this.signup.confirmPassword) {
 					this.signup.errors.confirmPassword = 'Passwords must match'
 				} else {
+					this.signup.loading = true
+
 					this.axios.post('/api/v1/user', {
 						username: this.signup.username,
 						password: this.signup.password
 					}).then(res => {
+						this.signup.loading = false
 						this.$store.commit('setUsername', res.data.username)
 						this.closeAccountModal()
 					}).catch(e => {
+						this.signup.loading = false
+
 						this.ajaxErrorHandler(e, (error) => {
 							let param = error.parameter
 
@@ -231,12 +242,16 @@
 					return
 				}
 
+				this.login.loading = true
+
 				this.axios.post(`/api/v1/user/${this.login.username}/login`, {
 					password: this.login.password
 				}).then(res => {
+					this.login.loading = false
 					this.$store.commit('setUsername', res.data.username)
 					this.closeAccountModal()
 				}).catch(e => {
+					this.login.loading = false
 					this.ajaxErrorHandler(e, (error) => {
 						let param = error.parameter
 

+ 57 - 0
src/components/LoadingButton.vue

@@ -0,0 +1,57 @@
+<template>
+	<div
+		class='button loading_button'
+		:class='{"loading_button--loading": loading}'
+		@click='event("click")'
+		@keydown='event("keydown")'
+	>
+		<div class='loading_button__icon'>
+			<span class='fa fa-refresh fa-spin'></span>
+		</div>
+		<div class='loading_button__slot'>
+			<slot></slot>
+		</div>
+	</div>
+</template>
+
+<script>
+	export default {
+		name: 'LoadingButton',
+		props: ['loading'],
+		methods: {
+			event (name) {
+				if(this.loading) {
+					return;
+				} else {
+					this.$emit(name)
+				}
+			}
+		}
+	}
+</script>
+
+<style lang='scss'>
+	.loading_button {
+		height: 2.25rem;
+		position: relative;
+		top: 0.76rem;
+		height: 2.4rem;
+		overflow: hidden;
+	}
+
+	.loading_button__icon {
+		margin-top: -2.25rem;
+		padding-bottom: 1rem;
+		transition: all 0.2s;
+	}
+
+	.loading_button--loading {
+		filter: grayscale(0.5);
+		cursor: not-allowed;
+
+		.loading_button__icon {
+			margin-top: 0rem;
+			transition: all 0.2s;
+		}
+	}
+</style>

+ 39 - 4
src/components/routes/Start.vue

@@ -26,7 +26,14 @@
 					placeholder='Confirm password'
 					type='password'
 				></fancy-input>
-				<button style='width: 100%;' class='button button--green' @click='createAccount'>Create account</button>
+				<loading-button
+					style='width: 100%;'
+					class='button button--green'
+					:loading='loading'
+					@click='createAccount'
+				>
+					Create account
+				</loading-button>
 			</div>
 		</div>
 		<div v-show='panel === 2'>
@@ -48,7 +55,14 @@
 					width='100%'
 					placeholder='Forum description'
 				></fancy-textarea>
-				<button style='width: 100%;' class='button button--green' @click='addSettings'>Add settings</button>
+				<loading-button
+					style='width: 100%;'
+					class='button button--green'
+					:loading='loading'
+					@click='addSettings'
+				>
+					Add settings
+				</loading-button>
 			</div>
 		</div>
 		<div v-show='panel === 3'>
@@ -70,7 +84,13 @@
 						width='100%'
 						placeholder='Category name'
 					></fancy-input>
-					<button class='button button--green' @click='addCategory'>Add category</button>
+					<loading-button
+						class='button button--green'
+						:loading='loading'
+						@click='addCategory'
+					>
+						Add category
+					</loading-button>
 				</div>
 			</div>
 			<button style='width: 100%;' class='button button--green' @click='finish'>Finish</button>
@@ -81,6 +101,7 @@
 <script>
 	import FancyInput from '../FancyInput'
 	import FancyTextarea from '../FancyTextarea'
+	import LoadingButton from '../LoadingButton'
 
 	import AjaxErrorHandler from '../../assets/js/errorHandler'
 
@@ -95,6 +116,8 @@
 				forumName: '',
 				forumDescription: '',
 
+				loading: false,
+
 				category: '',
 				categories: [],
 
@@ -117,7 +140,8 @@
 		},
 		components: {
 			FancyInput,
-			FancyTextarea
+			FancyTextarea,
+			LoadingButton
 		},
 		computed: {},
 		methods: {
@@ -130,6 +154,8 @@
 				this.errors.name = ''
 			},
 			errorCallback (err) {
+				this.loading = false
+
 				AjaxErrorHandler(this.$store)(err, (error, modalErrors) => {
 					if(this.errors[error.parameter] !== undefined) {
 						this.errors[error.parameter] = error.message
@@ -153,9 +179,12 @@
 					admin: true
 				})
 
+				this.loading = true
+
 				req.then(res => {
 					this.$store.commit('setUsername', res.data.username)
 					this.panel = 2
+					this.loading = false
 				}).catch(this.errorCallback)
 			},
 			addSettings () {
@@ -166,12 +195,15 @@
 					return
 				}
 
+				this.loading = true
+
 				let settingsReq = this.axios.put('/api/v1/settings', {
 					forumName: this.forumName,
 					forumDescription: this.forumDescription
 				})
 
 				settingsReq.then(res => {
+					this.loading = false
 					this.$store.commit('setForumName', res.data.forumName)
 					this.panel = 3
 				}).catch(this.errorCallback)
@@ -184,9 +216,12 @@
 					return
 				}
 
+				this.loading = true
+
 				this.axios.post('/api/v1/category', {
 					name: this.category.trim()
 				}).then(res => {
+					this.loading = false
 					this.$store.commit('addCategories', res.data.name)
 					this.categories.push(res.data.name)
 				}).catch(this.errorCallback)