Large refactor on the front end
Created pages directory Added night mode
This commit is contained in:
		
							
								
								
									
										257
									
								
								client/src/pages/NotesPage.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										257
									
								
								client/src/pages/NotesPage.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,257 @@ | ||||
| <template> | ||||
| 	<div class="ui basic segment"> | ||||
| 		 | ||||
|  | ||||
| 		<div class="ui equal width grid"> | ||||
|  | ||||
| 			<!-- mobile search menu --> | ||||
| 			<div class="ui mobile only row"> | ||||
| 				<!-- Small screen new note button --> | ||||
| 				<div class="ui four wide column"> | ||||
| 					<div @click="createNote" class="ui fluid green icon button"> | ||||
| 						<i class="plus icon"></i> | ||||
| 					</div> | ||||
| 				</div> | ||||
|  | ||||
| 				<div class="ui twelve wide column"> | ||||
| 					<div class="ui form"> | ||||
| 						<input v-model="searchTerm" @keyup="searchKeyUp" @:keyup.enter="search" placeholder="Search Notes" /> | ||||
| 					</div> | ||||
| 				</div> | ||||
| 			</div> | ||||
|  | ||||
| 			<!-- search menu  --> | ||||
| 			<div class="ui large screen only row"> | ||||
|  | ||||
| 				<div class="ui two wide column"> | ||||
| 					<div @click="createNote" class="ui fluid green button"> | ||||
| 						<i class="plus icon"></i> | ||||
| 						New Note | ||||
| 					</div> | ||||
| 				</div> | ||||
| 				 | ||||
| 				<div class="ui five wide column"> | ||||
| 					<div class="ui form"> | ||||
| 						<input v-model="searchTerm" @keyup="searchKeyUp" @:keyup.enter="search" placeholder="Search Notes" /> | ||||
| 					</div> | ||||
| 				</div> | ||||
|  | ||||
| 				<div class="ui nine wide column"> | ||||
| 					 | ||||
| 					<router-link class="ui basic button" to="/help">Help</router-link> | ||||
|  | ||||
| 					<div v-on:click="toggleNightMode" class="ui basic button"> | ||||
| 						Dark Theme:  | ||||
| 						<span v-if="$store.getters.getIsNightMode">On</span> | ||||
| 						<span v-else>Off</span> | ||||
| 					</div> | ||||
|  | ||||
| 					<div class="ui right floated basic button"  | ||||
| 					data-tooltip="Log Out" data-position="left center" | ||||
| 					v-on:click="destroyLoginToken">{{username}}</div> | ||||
| 				</div> | ||||
| 			</div> | ||||
|  | ||||
| 			<div class="ui row"> | ||||
|  | ||||
| 				<!-- tags display  --> | ||||
| 				<div class="ui two wide large screen only column"> | ||||
| 					<div class="ui basic fluid button" @click="reset"><i class="undo icon"></i>All Notes</div> | ||||
| 					<div class="ui divider"></div> | ||||
| 					<div class="ui section list"> | ||||
| 						<div class="item" v-for="tag in commonTags" @click="toggleTagFilter(tag.id)"> | ||||
| 							<div class="ui clickable basic fluid large label" :class="{ 'green':(searchTags.includes(tag.id)) }"> | ||||
| 							{{ucWords(tag.text)}} <div class="detail">{{tag.usages}}</div> | ||||
| 							</div> | ||||
| 						</div> | ||||
| 					</div> | ||||
| 				</div> | ||||
|  | ||||
| 				<!-- Note title cards  --> | ||||
| 				<div class="ui fourteen wide computer sixteen wide mobile column"> | ||||
| 					<h2> | ||||
| 						Notes ({{notes.length}}) | ||||
| 					</h2> | ||||
| 					<div v-if="notes !== null" class="note-card-display-area" :class="{'one-column':(activeNoteId1 != null || activeNoteId2 != null )}"> | ||||
| 						<note-title-display-card  | ||||
| 							v-for="note in notes"  | ||||
| 							:onClick="openNote" | ||||
| 							:data="note" | ||||
| 							:key="note.id + note.color + searchTerm + note.note_highlights.length + note.attachment_highlights.length + ' -' + note.tag_highlights.length + '-' +note.title.length + '-' +note.subtext.length" | ||||
| 						/> | ||||
| 					</div> | ||||
|  | ||||
| 				</div> | ||||
| 			</div> | ||||
| 		</div> | ||||
|  | ||||
| 		 | ||||
| 		<input-notes v-if="activeNoteId1 != null" :noteid="activeNoteId1" :position="activeNote1Position" /> | ||||
| 		<input-notes v-if="activeNoteId2 != null" :noteid="activeNoteId2" :position="activeNote2Position" /> | ||||
|  | ||||
| 	</div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| 	 | ||||
| 	import axios from 'axios'; | ||||
|  | ||||
| 	export default { | ||||
| 	name: 'SearchBar', | ||||
| 		components: { | ||||
| 			'input-notes': require('@/components/NoteInputPanel.vue').default, | ||||
| 			'note-title-display-card': require('@/components/NoteTitleDisplayCard.vue').default, | ||||
| 		}, | ||||
| 		data () { | ||||
| 			return { | ||||
| 				username:'', | ||||
| 				initComponent: true, | ||||
| 				commonTags: [], | ||||
| 				searchTerm: '', | ||||
| 				searchTags: [], | ||||
| 				notes: [], | ||||
| 				searchDebounce: null, | ||||
|  | ||||
| 				//Currently open notes in app | ||||
| 				activeNoteId1: null, | ||||
| 				activeNoteId2: null, | ||||
| 				//Position determines how note is Positioned | ||||
| 				activeNote1Position: 0, | ||||
| 				activeNote2Position: 0, | ||||
| 			} | ||||
| 		}, | ||||
| 		beforeMount(){ | ||||
|  | ||||
| 			let username = this.$store.getters.getUsername | ||||
| 			this.username = this.ucWords(username) | ||||
|  | ||||
| 			this.$bus.$on('close_active_note', position => { | ||||
| 				this.closeNote(position) | ||||
| 			}) | ||||
| 			this.$bus.$on('note_deleted', () => { | ||||
| 				this.search() | ||||
| 			}) | ||||
| 			 | ||||
| 		}, | ||||
| 		mounted() { | ||||
|  | ||||
| 			this.search() | ||||
|  | ||||
| 		}, | ||||
| 		methods: { | ||||
| 			openNote(id){ | ||||
|  | ||||
| 				//Do not open same note twice | ||||
| 				if(this.activeNoteId1 == id || this.activeNoteId2 == id){ | ||||
| 					return; | ||||
| 				} | ||||
|  | ||||
| 				//1 note open | ||||
| 				if(this.activeNoteId1 == null && this.activeNoteId2 == null){ | ||||
| 					this.activeNoteId1 = id | ||||
| 					this.activeNote1Position = 0 //Middel of page | ||||
| 					return | ||||
| 				} | ||||
| 				//2 notes open | ||||
| 				if(this.activeNoteId1 != null && this.activeNoteId2 == null){ | ||||
| 					this.activeNoteId2 = id | ||||
| 					this.activeNote1Position = 1 //Right side of page | ||||
| 					this.activeNote2Position = 2 //Left side of page | ||||
| 					return | ||||
| 				} | ||||
| 			}, | ||||
| 			closeNote(position){ | ||||
| 				//One note open, close that note | ||||
| 				if(position == 0){ | ||||
| 					this.activeNoteId1 = null | ||||
| 					this.activeNoteId2 = null | ||||
| 				} | ||||
| 				//Right note closed, thats 1 | ||||
| 				if(position == 1){ | ||||
| 					this.activeNoteId1 = null | ||||
| 				} | ||||
| 				if(position == 2){ | ||||
| 					this.activeNoteId2 = null | ||||
| 				} | ||||
|  | ||||
| 				this.activeNote1Position = 0 | ||||
| 				this.activeNote2Position = 0 | ||||
|  | ||||
| 				this.search() | ||||
| 			}, | ||||
| 			toggleTagFilter(tagId){ | ||||
|  | ||||
| 				if(this.searchTags.includes(tagId)){ | ||||
| 					this.searchTags.splice( this.searchTags.indexOf(tagId) , 1); | ||||
| 				} else { | ||||
| 					this.searchTags.push(tagId) | ||||
| 				} | ||||
|  | ||||
| 				this.search() | ||||
| 			}, | ||||
| 			search(){ | ||||
| 				let postData = { | ||||
| 					searchQuery: this.searchTerm, | ||||
| 					searchTags: this.searchTags | ||||
| 				} | ||||
| 				//Perform search | ||||
| 				let vm = this | ||||
| 				axios.post('/api/notes/search', postData). | ||||
| 				then(response => { | ||||
| 					console.log('Notes and Tags') | ||||
| 					console.log(response.data) | ||||
|  | ||||
| 					vm.commonTags = response.data.tags | ||||
| 					vm.notes = response.data.notes | ||||
| 					vm.highlights = response.data.highlights | ||||
| 				}) | ||||
| 			}, | ||||
| 			searchKeyUp(){ | ||||
| 				let vm = this | ||||
| 				clearTimeout(vm.searchDebounce) | ||||
| 				vm.searchDebounce = setTimeout(() => { | ||||
| 					vm.search() | ||||
| 				}, 300) | ||||
| 			}, | ||||
| 			createNote(event){ | ||||
| 				const title = '' | ||||
| 				let vm = this | ||||
|  | ||||
| 				axios.post('/api/notes/create', {title}) | ||||
| 				.then(response => { | ||||
|  | ||||
| 					if(response.data && response.data.id){ | ||||
| 						vm.openNote(response.data.id) | ||||
| 					} | ||||
| 				}) | ||||
| 			}, | ||||
| 			ucWords(str){ | ||||
| 				return (str + '') | ||||
| 				.replace(/^(.)|\s+(.)/g, function ($1) { | ||||
| 					return $1.toUpperCase() | ||||
| 				}) | ||||
| 			}, | ||||
| 			reset(){ | ||||
| 				this.searchTerm = '' | ||||
| 				this.searchTags = [] | ||||
| 				this.search() | ||||
| 			}, | ||||
| 			destroyLoginToken() { | ||||
| 				this.$store.commit('destroyLoginToken') | ||||
| 				this.$router.push('/') | ||||
| 			}, | ||||
| 			toggleNightMode(){ | ||||
| 				this.$store.commit('toggleNightMode') | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| </script> | ||||
| <style type="text/css" scoped> | ||||
| 	.detail { | ||||
| 		float: right; | ||||
| 	} | ||||
| 	.note-card-display-area { | ||||
| 		display: flex; | ||||
| 		flex-wrap: wrap; | ||||
| 	} | ||||
| </style> | ||||
		Reference in New Issue
	
	Block a user