| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368 | <template>	<div>		<div class="container">			<table class="table is-striped">				<thead>					<tr>						<td>Title</td>						<td>Description</td>						<td>Bugs</td>						<td>Features</td>						<td>Improvements</td>						<td>Upcoming</td>						<td>Options</td>					</tr>				</thead>				<tbody>					<tr v-for="(news, index) in news" :key="index">						<td>							<strong>{{ news.title }}</strong>						</td>						<td>{{ news.description }}</td>						<td>{{ news.bugs.join(", ") }}</td>						<td>{{ news.features.join(", ") }}</td>						<td>{{ news.improvements.join(", ") }}</td>						<td>{{ news.upcoming.join(", ") }}</td>						<td>							<button								class="button is-primary"								@click="editNews(news)"							>								Edit							</button>							<button								class="button is-danger"								@click="removeNews(news)"							>								Remove							</button>						</td>					</tr>				</tbody>			</table>			<div class="card is-fullwidth">				<header class="card-header">					<p class="card-header-title">						Create News					</p>				</header>				<div class="card-content">					<div class="content">						<label class="label">Title & Description</label>						<div class="control is-horizontal">							<div class="control is-grouped">								<p class="control is-expanded">									<input										v-model="creating.title"										class="input"										type="text"										placeholder="Title"									/>								</p>								<p class="control is-expanded">									<input										v-model="creating.description"										class="input"										type="text"										placeholder="Short description"									/>								</p>							</div>						</div>						<div class="columns">							<div class="column">								<label class="label">Bugs</label>								<p class="control has-addons">									<input										id="new-bugs"										class="input"										type="text"										placeholder="Bug"										@keyup.enter="addChange('bugs')"									/>									<a										class="button is-info"										href="#"										@click="addChange('bugs')"										>Add</a									>								</p>								<span									v-for="(bug, index) in creating.bugs"									:key="index"									class="tag is-info"								>									{{ bug }}									<button										class="delete is-info"										@click="removeChange('bugs', index)"									/>								</span>							</div>							<div class="column">								<label class="label">Features</label>								<p class="control has-addons">									<input										id="new-features"										class="input"										type="text"										placeholder="Feature"										@keyup.enter="addChange('features')"									/>									<a										class="button is-info"										href="#"										@click="addChange('features')"										>Add</a									>								</p>								<span									v-for="(feature,									index) in creating.features"									:key="index"									class="tag is-info"								>									{{ feature }}									<button										class="delete is-info"										@click="removeChange('features', index)"									/>								</span>							</div>						</div>						<div class="columns">							<div class="column">								<label class="label">Improvements</label>								<p class="control has-addons">									<input										id="new-improvements"										class="input"										type="text"										placeholder="Improvement"										@keyup.enter="addChange('improvements')"									/>									<a										class="button is-info"										href="#"										@click="addChange('improvements')"										>Add</a									>								</p>								<span									v-for="(improvement,									index) in creating.improvements"									:key="index"									class="tag is-info"								>									{{ improvement }}									<button										class="delete is-info"										@click="											removeChange('improvements', index)										"									/>								</span>							</div>							<div class="column">								<label class="label">Upcoming</label>								<p class="control has-addons">									<input										id="new-upcoming"										class="input"										type="text"										placeholder="Upcoming"										@keyup.enter="addChange('upcoming')"									/>									<a										class="button is-info"										href="#"										@click="addChange('upcoming')"										>Add</a									>								</p>								<span									v-for="(upcoming,									index) in creating.upcoming"									:key="index"									class="tag is-info"								>									{{ upcoming }}									<button										class="delete is-info"										@click="removeChange('upcoming', index)"									/>								</span>							</div>						</div>					</div>				</div>				<footer class="card-footer">					<a class="card-footer-item" @click="createNews()" href="#"						>Create</a					>				</footer>			</div>		</div>		<edit-news v-if="modals.editNews" />	</div></template><script>import { mapActions, mapState } from "vuex";import { Toast } from "vue-roaster";import io from "../../io";import EditNews from "../Modals/EditNews.vue";export default {	components: { EditNews },	data() {		return {			news: [],			creating: {				title: "",				description: "",				bugs: [],				features: [],				improvements: [],				upcoming: []			},			editing: {}		};	},	mounted: function() {		let _this = this;		io.getSocket(socket => {			_this.socket = socket;			_this.socket.emit(				"news.index",				result => (_this.news = result.data)			);			_this.socket.on("event:admin.news.created", news => {				_this.news.unshift(news);			});			_this.socket.on("event:admin.news.removed", news => {				_this.news = _this.news.filter(item => item._id !== news._id);			});			if (_this.socket.connected) _this.init();			io.onConnect(() => _this.init());		});	},	computed: {		...mapState("modals", {			modals: state => state.modals.admin		})	},	methods: {		createNews: function() {			let _this = this;			let {				creating: { bugs, features, improvements, upcoming }			} = this;			if (this.creating.title === "")				return Toast.methods.addToast(					"Field (Title) cannot be empty",					3000				);			if (this.creating.description === "")				return Toast.methods.addToast(					"Field (Description) cannot be empty",					3000				);			if (				bugs.length <= 0 &&				features.length <= 0 &&				improvements.length <= 0 &&				upcoming.length <= 0			)				return Toast.methods.addToast(					"You must have at least one News Item",					3000				);			_this.socket.emit("news.create", _this.creating, result => {				Toast.methods.addToast(result.message, 4000);				if (result.status == "success")					_this.creating = {						title: "",						description: "",						bugs: [],						features: [],						improvements: [],						upcoming: []					};			});		},		removeNews: function(news) {			this.socket.emit("news.remove", news, res =>				Toast.methods.addToast(res.message, 8000)			);		},		editNews: function(news) {			this.editing = news;			this.toggleModal({ sector: "admin", modal: "editNews" });		},		updateNews: function(close) {			let _this = this;			this.socket.emit(				"news.update",				_this.editing._id,				_this.editing,				res => {					Toast.methods.addToast(res.message, 4000);					if (res.status === "success") {						if (close)							_this.toggleModal({								sector: "admin",								modal: "editNews"							});					}				}			);		},		addChange: function(type) {			let change = document.getElementById(`new-${type}`).value.trim();			if (this.creating[type].indexOf(change) !== -1)				return Toast.methods.addToast(`Tag already exists`, 3000);			if (change) {				document.getElementById(`new-${type}`).value = "";				this.creating[type].push(change);			} else Toast.methods.addToast(`${type} cannot be empty`, 3000);		},		removeChange: function(type, index) {			this.creating[type].splice(index, 1);		},		init: function() {			this.socket.emit("apis.joinAdminRoom", "news", () => {});		},		...mapActions("modals", ["toggleModal"])	}};</script><style lang="scss" scoped>.tag:not(:last-child) {	margin-right: 5px;}td {	vertical-align: middle;}.is-info:focus {	background-color: #0398db;}.card-footer-item {	color: #03a9f4;}</style>
 |