Browse Source

Finished creating of Reports on backend and refactored part of frontend

theflametrooper 8 years ago
parent
commit
4a35b2e5c8

+ 1 - 0
backend/logic/actions/index.js

@@ -7,5 +7,6 @@ module.exports = {
 	stations: require('./stations'),
 	playlists: require('./playlists'),
 	users: require('./users'),
+	reports: require('./reports'),
 	news: require('./news')
 };

+ 78 - 3
backend/logic/actions/reports.js

@@ -1,5 +1,7 @@
 'use strict';
 
+const async = require('async');
+
 const db = require('../db');
 const hooks = require('./hooks');
 
@@ -7,13 +9,86 @@ module.exports = {
 
 	index: hooks.adminRequired((session, cb) => {
 		db.models.reports.find({}).sort({ released: 'desc' }).exec((err, reports) => {
-			if (err) throw err;
+			if (err) console.error(err);
 			else cb({ status: 'success', data: reports });
 		});
 	}),
 
-	create: hooks.loginRequired((session, report, cb) => {
-		console.log(report);
+	create: hooks.loginRequired((session, data, cb) => {
+		async.waterfall([
+
+			(next) => {
+				db.models.report.find({ createdBy: data.createdBy, createdAt: data.createdAt }).exec((err, report) => {
+					if (err) console.error(err);
+					if (report) return cb({ status: 'failure', message: 'Report already exists' });
+					else next();
+				});
+			},
+
+			(next) => {
+				let issues = [
+					{
+						name: 'Video',
+						reasons: [
+							'Doesn\'t exist',
+							'It\'s private',
+							'It\'s not available in my country'
+						]
+					},
+					{
+						name: 'Title',
+						reasons: [
+							'Incorrect',
+							'Inappropriate'
+						]
+					},
+					{
+						name: 'Duration',
+						reasons: [
+							'Skips too soon',
+							'Skips too late',
+							'Starts too soon',
+							'Skips too late'
+						]
+					},
+					{
+						name: 'Artists',
+						reasons: [
+							'Incorrect',
+							'Inappropriate'
+						]
+					},
+					{
+						name: 'Thumbnail',
+						reasons: [
+							'Incorrect',
+							'Inappropriate',
+							'Doesn\'t exist'
+						]
+					}
+				];
+
+				for (let z = 0; z < data.issues.length; z++) {
+					if (issues.filter(issue => { return issue.name == data.issues[z].name; }).length > 0) {
+						for (let r = 0; r < issues.length; r++) {
+							if (issues[r].reasons.every(reason => data.issues[z].reasons.indexOf(reason) < -1)) {
+								return cb({ 'status': 'failure', 'message': 'Invalid data' });
+							}
+						}
+					} else return cb({ 'status': 'failure', 'message': 'Invalid data' });
+				}
+
+				next();
+			},
+
+			(next) => {
+				db.models.report.create(data, next);
+			}
+
+		], err => {
+			if (err) return cb({ 'status': 'failure', 'message': 'Something went wrong'});
+			return cb({ 'status': 'success', 'message': 'Successfully created report' });
+		});
 	})
 
 };

+ 2 - 2
backend/logic/db/index.js

@@ -23,7 +23,7 @@ let lib = {
 				user: new mongoose.Schema(require(`./schemas/user`)),
 				playlist: new mongoose.Schema(require(`./schemas/playlist`)),
 				news: new mongoose.Schema(require(`./schemas/news`)),
-				reports: new mongoose.Schema(require(`./schemas/reports`))
+				report: new mongoose.Schema(require(`./schemas/report`))
 			};
 
 			lib.schemas.station.path('_id').validate((id) => {
@@ -37,7 +37,7 @@ let lib = {
 				user: mongoose.model('user', lib.schemas.user),
 				playlist: mongoose.model('playlist', lib.schemas.playlist),
 				news: mongoose.model('news', lib.schemas.news),
-				reports: mongoose.model('reports', lib.schemas.reports)
+				report: mongoose.model('report', lib.schemas.report)
 			};
 
 			cb();

+ 5 - 1
backend/logic/db/schemas/reports.js → backend/logic/db/schemas/report.js

@@ -1,6 +1,10 @@
 module.exports = {
-	title: { type: String, required: true },
+	songId: { type: String, required: true },
 	description: { type: String, required: true },
+	issues: [{
+		name: String,
+		reasons: Array
+	}],
 	createdBy: { type: String, required: true },
 	createdAt: { type: Date, default: Date.now(), required: true }
 };

+ 92 - 110
frontend/components/Modals/Report.vue

@@ -64,122 +64,28 @@
 					</div>
 				</div>
 				<div class='edit-report-wrapper'>
-					<div class='columns'>
-						<div class='column'>
-							<label class='label'>Video</label>
-							<p class='control'>
-								<label class='checkbox'>
-									<input type='checkbox'>
-									Doesn't exist
-								</label>
-							</p>
-							<p class='control'>
-								<label class='checkbox'>
-									<input type='checkbox'>
-									It's Private
-								</label>
-							</p>
-							<p class='control'>
-								<label class='checkbox'>
-									<input type='checkbox'>
-									It's not available in my country
-								</label>
-							</p>
-						</div>
-						<div class='column'>
-							<label class='label'>Title</label>
-							<p class='control'>
-								<label class='checkbox'>
-									<input type='checkbox'>
-									Incorrect
-								</label>
-							</p>
-							<p class='control'>
-								<label class='checkbox'>
-									<input type='checkbox'>
-									Inappropriate
-								</label>
-							</p>
-						</div>
-					</div>
-					<div class='columns'>
-						<div class='column'>
-							<label class='label'>Duration</label>
-							<p class='control'>
-								<label class='checkbox'>
-									<input type='checkbox'>
-									Skips too soon
-								</label>
-							</p>
-							<p class='control'>
-								<label class='checkbox'>
-									<input type='checkbox'>
-									Skips too late
-								</label>
-							</p>
-							<p class='control'>
-								<label class='checkbox'>
-									<input type='checkbox'>
-									Starts too soon
-								</label>
-							</p>
-							<p class='control'>
-								<label class='checkbox'>
-									<input type='checkbox'>
-									Starts too late
-								</label>
-							</p>
-						</div>
-						<div class='column'>
-							<label class='label'>Artists</label>
-							<p class='control'>
-								<label class='checkbox'>
-									<input type='checkbox'>
-									Incorrect
-								</label>
-							</p>
-							<p class='control'>
-								<label class='checkbox'>
-									<input type='checkbox'>
-									Inappropriate
-								</label>
-							</p>
-						</div>
-					</div>
-					<div class='columns'>
-						<div class='column'>
-							<label class='label'>Thumbnail</label>
-							<p class='control'>
-								<label class='checkbox'>
-									<input type='checkbox'>
-									Incorrect
-								</label>
-							</p>
-							<p class='control'>
-								<label class='checkbox'>
-									<input type='checkbox'>
-									Inappropriate
-								</label>
-							</p>
-							<p class='control'>
+					<div class='columns is-multiline'>
+						<div class='column is-half' v-for='issue in issues'>
+							<label class='label'>{{ issue.name }}</label>
+							<p class='control' v-for='reason in issue.reasons' track-by='$index'>
 								<label class='checkbox'>
-									<input type='checkbox'>
-									Doesn't exist
+									<input type='checkbox' @click='toggleIssue(issue.name, reason)'>
+									{{ reason }}
 								</label>
 							</p>
 						</div>
 						<div class='column'>
 							<label class='label'>Other</label>
-							<textarea class='textarea' maxlength='400' placeholder='Any other details...' @keyup='updateCharactersRemaining()'></textarea>
+							<textarea class='textarea' maxlength='400' placeholder='Any other details...' @keyup='updateCharactersRemaining()' v-model='report.description'></textarea>
 							<div class='textarea-counter'>{{ charactersRemaining }}</div>
 						</div>
 					</div>
 				</div>
 			</section>
 			<footer class='modal-card-foot'>
-				<a class='button is-success' @click='save()'>
+				<a class='button is-success' @click='create()'>
 					<i class='material-icons save-changes'>done</i>
-					<span>&nbsp;Submit Report</span>
+					<span>&nbsp;Create</span>
 				</a>
 				<a class='button is-danger' @click='$parent.modals.report = !$parent.modals.report'>
 					<span>&nbsp;Cancel</span>
@@ -190,40 +96,116 @@
 </template>
 
 <script>
+	import { Toast } from 'vue-roaster';
+
 	export default {
 		data() {
 			return {
 				charactersRemaining: 400,
 				isPreviousSongActive: false,
 				isCurrentSongActive: true,
-				report: {}
+				report: {
+					songId: this.$parent.currentSong._id,
+					description: '',
+					issues: [
+						{ name: 'Video', reasons: [] },
+						{ name: 'Title', reasons: [] },
+						{ name: 'Duration', reasons: [] },
+						{ name: 'Artists', reasons: [] },
+						{ name: 'Thumbnail', reasons: [] }
+					],
+					createdBy: this.$parent.$parent.userId,
+					createdAt: Date.now()
+				},
+				issues: [
+					{
+						name: 'Video',
+						reasons: [
+							'Doesn\'t exist',
+							'It\'s private',
+							'It\'s not available in my country'
+						]
+					},
+					{
+						name: 'Title',
+						reasons: [
+							'Incorrect',
+							'Inappropriate'
+						]
+					},
+					{
+						name: 'Duration',
+						reasons: [
+							'Skips too soon',
+							'Skips too late',
+							'Starts too soon',
+							'Skips too late'
+						]
+					},
+					{
+						name: 'Artists',
+						reasons: [
+							'Incorrect',
+							'Inappropriate'
+						]
+					},
+					{
+						name: 'Thumbnail',
+						reasons: [
+							'Incorrect',
+							'Inappropriate',
+							'Doesn\'t exist'
+						]
+					}
+				]
 			}
 		},
 		methods: {
-			save: function () {
-				// this.socket.emit('reports.updateDisplayName', this.$parent.stationId, this.$parent.station.displayName, res => {
-				// 	if (res.status == 'success') return Toast.methods.addToast(res.message, 4000);
-				// 	Toast.methods.addToast(res.message, 8000);
-				// });
+			create: function () {
+				this.socket.emit('reports.create', this.report, res => {
+					Toast.methods.addToast(res.message, 4000);
+				});
 			},
 			updateCharactersRemaining: function () {
 				this.charactersRemaining = 400 - $('.textarea').val().length;
 			},
 			highlight: function (type) {
 				if (type == 'currentSong') {
+					this.report.songId = this.$parent.currentSong._id;
 					this.isPreviousSongActive = false;
 					this.isCurrentSongActive = true;
 				} else if (type == 'previousSong') {
+					this.report.songId = this.$parent.previousSong._id;
 					this.isCurrentSongActive = false;
 					this.isPreviousSongActive = true;
 				}
+			},
+			toggleIssue: function (name, reason) {
+				for (let z = 0; z < this.report.issues.length; z++) {
+					if (this.report.issues[z].name == name) {
+						if (this.report.issues[z].reasons.indexOf(reason) > -1) {
+							this.report.issues[z].reasons.splice(
+								this.report.issues[z].reasons.indexOf(reason), 1
+							);
+						} else this.report.issues[z].reasons.push(reason);
+					}
+				}
 			}
 		},
 		events: {
 			closeModal: function () {
 				this.$parent.toggleModal('report');
 			}
-		}
+		},
+		ready: function () {
+			let _this = this;
+			let socketInterval = setInterval(() => {
+				if (!!_this.$parent.socket) {
+					_this.socket = _this.$parent.socket;
+					clearInterval(socketInterval);
+				}
+			}, 100);
+		},
 	}
 </script>