소스 검색

Add error handling for new thread page and for input editor

sbkwgh 8 년 전
부모
커밋
ad7bd137e2
2개의 변경된 파일64개의 추가작업 그리고 4개의 파일을 삭제
  1. 45 1
      src/components/InputEditor.vue
  2. 19 3
      src/components/routes/ThreadNew.vue

+ 45 - 1
src/components/InputEditor.vue

@@ -7,6 +7,12 @@
 			"input_editor--hidden": !show
 		}'
 	>
+		<div
+			class='input_editor__error'
+			:class='{"input_editor__error--show": error }'
+		>
+			{{error}}
+		</div>
 		<div class='input_editor__reply_username' v-if='replyUsername'>Replying to <strong>{{replyUsername}}</strong></div>
 		<div class='input_editor__close input_editor__format_button' @click='closeEditor' v-if='!hideClose'>&times;</div>
 		<tab-view :tabs='["Editor", "Preview"]' v-model='showTab' small-tabs='true'>
@@ -72,7 +78,7 @@
 
 	export default {
 		name: 'InputEditor',
-		props: ['value', 'float', 'replyUsername', 'hideClose', 'show'],
+		props: ['value', 'float', 'replyUsername', 'hideClose', 'show', 'error'],
 		components: {
 			ModalWindow,
 			FancyInput,
@@ -317,5 +323,43 @@
 				border-color: $color__gray--darkest;
 			}
 		}
+
+		@at-root #{&}__error {
+			position: absolute;
+			background-color: #ffeff1;
+			border: 0.125rem solid #D32F2F;
+			font-size: 0.9rem;
+			padding: 0.1rem 0.25rem;
+			top: 0.2125rem;
+			left: calc(100% + 0.25rem);
+			white-space: nowrap;
+			
+
+			&:first-letter{ text-transform: capitalize; }
+
+			opacity: 0;
+			pointer-events: none;
+			margin-top: -1rem;
+			transition: opacity 0.2s, margin-top 0.2s;
+
+			@at-root #{&}--show {
+				opacity: 1;
+				pointer-events: all;
+				margin-top: 0;
+				transition: opacity 0.2s, margin-top 0.2s;
+			}
+
+			&::after {
+				content: '';
+				position: relative;
+				width: 0;
+				height: 0;
+				display: inline-block;
+				right: calc(100% + 0.3rem);
+				border-top: 0.3rem solid transparent;
+				border-bottom: 0.3rem solid transparent;
+				border-right: 0.3rem solid #D32F2F;
+			}
+		}
 	}
 </style>

+ 19 - 3
src/components/routes/ThreadNew.vue

@@ -7,8 +7,8 @@
 			<span class='select_button_text'>Name of thread:</span>
 			<fancy-input placeholder='Thread name' v-model='name' style='display: inline-block;'></fancy-input>
 		</div>
-		<input-editor v-model='editor' :show='true' :hide-close='true' style='margin-top: 1rem'></input-editor>
-		<button class='button button--green submit' @click='postThread'>Post thread</button>
+		<input-editor v-model='editor' :show='true' :hide-close='true' :error='errors.content' style='margin-top: 1rem'></input-editor>
+		<loading-button class='button--green submit' :loading='loading' @click='postThread'>Post thread</loading-button>
 	</div>
 </template>
 
@@ -16,6 +16,7 @@
 	import InputEditor from '../InputEditor'
 	import FancyInput from '../FancyInput'
 	import SelectButton from '../SelectButton'
+	import LoadingButton from '../LoadingButton'
 
 	import AjaxErrorHandler from '../../assets/js/errorHandler'
 	
@@ -24,13 +25,15 @@
 		components: {
 			InputEditor,
 			SelectButton,
-			FancyInput
+			FancyInput,
+			LoadingButton
 		},
 		data () {
 			return {
 				selectedCategory: this.$store.state.category.selectedCategory,
 				editor: '',
 				name: '',
+				loading: false,
 
 				errors: {
 					content: '',
@@ -45,6 +48,16 @@
 		},
 		methods: {
 			postThread () {
+				if(!this.editor.trim().length) {
+					this.errors.content = 'Cannot be blank'
+					return;
+				} 
+
+				this.errors.content = ''
+				this.errors.name = ''
+
+				this.loading = true
+
 				this.axios.post('/api/v1/thread', {
 					name: this.name,
 					category: this.selectedCategory
@@ -54,8 +67,11 @@
 						content: this.editor
 					})
 				}).then(res => {
+					this.loading = false
 					this.$router.push(`/thread/${res.data.Thread.slug}/${res.data.Thread.id}`)
 				}).catch(e => {
+					this.loading = false
+
 					AjaxErrorHandler(this.$store)(e, (error, errors) => {
 						let param = error.parameter