| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375 | <template>	<div>		<metadata title="Admin | Stations" />		<div class="container">			<table class="table is-striped">				<thead>					<tr>						<td>ID</td>						<td>Name</td>						<td>Type</td>						<td>Display Name</td>						<td>Description</td>						<td>Owner</td>						<td>Options</td>					</tr>				</thead>				<tbody>					<tr v-for="(station, index) in stations" :key="index">						<td>							<span>{{ station._id }}</span>						</td>						<td>							<span>								<router-link									:to="{										name: 'station',										params: { id: station.name }									}"								>									{{ station.name }}								</router-link>							</span>						</td>						<td>							<span>{{ station.type }}</span>						</td>						<td>							<span>{{ station.displayName }}</span>						</td>						<td>							<span>{{ station.description }}</span>						</td>						<td>							<span								v-if="station.type === 'official'"								title="Musare"								>Musare</span							>							<user-id-to-username								v-else								:userId="station.owner"								:link="true"							/>						</td>						<td>							<a class="button is-info" v-on:click="edit(station)"								>Edit</a							>							<a								class="button is-danger"								href="#"								@click="removeStation(index)"								>Remove</a							>						</td>					</tr>				</tbody>			</table>		</div>		<div class="container">			<div class="card is-fullwidth">				<header class="card-header">					<p class="card-header-title">						Create official station					</p>				</header>				<div class="card-content">					<div class="content">						<div class="control is-horizontal">							<div class="control is-grouped">								<p class="control is-expanded">									<input										v-model="newStation.name"										class="input"										type="text"										placeholder="Name"									/>								</p>								<p class="control is-expanded">									<input										v-model="newStation.displayName"										class="input"										type="text"										placeholder="Display Name"									/>								</p>							</div>						</div>						<label class="label">Description</label>						<p class="control is-expanded">							<input								v-model="newStation.description"								class="input"								type="text"								placeholder="Short description"							/>						</p>						<div class="control is-grouped genre-wrapper">							<div class="sector">								<p class="control has-addons">									<input										id="new-genre"										class="input"										type="text"										placeholder="Genre"										@keyup.enter="addGenre()"									/>									<a										class="button is-info"										href="#"										@click="addGenre()"										>Add genre</a									>								</p>								<span									v-for="(genre, index) in newStation.genres"									:key="index"									class="tag is-info"								>									{{ genre }}									<button										class="delete is-info"										@click="removeGenre(index)"									/>								</span>							</div>							<div class="sector">								<p class="control has-addons">									<input										id="new-blacklisted-genre"										class="input"										type="text"										placeholder="Blacklisted Genre"										@keyup.enter="addBlacklistedGenre()"									/>									<a										class="button is-info"										href="#"										@click="addBlacklistedGenre()"										>Add blacklisted genre</a									>								</p>								<span									v-for="(genre,									index) in newStation.blacklistedGenres"									:key="index"									class="tag is-info"								>									{{ genre }}									<button										class="delete is-info"										@click="removeBlacklistedGenre(index)"									/>								</span>							</div>						</div>					</div>				</div>				<footer class="card-footer">					<a						class="card-footer-item"						href="#"						@click="createStation()"						>Create</a					>				</footer>			</div>		</div>		<edit-station v-if="modals.editStation" />	</div></template><script>import { mapState, mapActions } from "vuex";import { Toast } from "vue-roaster";import io from "../../io";import EditStation from "./EditStation.vue";import UserIdToUsername from "../UserIdToUsername.vue";export default {	components: { EditStation, UserIdToUsername },	data() {		return {			stations: [],			newStation: {				genres: [],				blacklistedGenres: []			}		};	},	computed: {		...mapState("modals", {			modals: state => state.modals.station		})	},	methods: {		createStation() {			const {				newStation: {					name,					displayName,					description,					genres,					blacklistedGenres				}			} = this;			if (name === undefined)				return Toast.methods.addToast(					"Field (Name) cannot be empty",					3000				);			if (displayName === undefined)				return Toast.methods.addToast(					"Field (Display Name) cannot be empty",					3000				);			if (description === undefined)				return Toast.methods.addToast(					"Field (Description) cannot be empty",					3000				);			return this.socket.emit(				"stations.create",				{					name,					type: "official",					displayName,					description,					genres,					blacklistedGenres				},				result => {					Toast.methods.addToast(result.message, 3000);					if (result.status === "success")						this.newStation = {							genres: [],							blacklistedGenres: []						};				}			);		},		removeStation(index) {			this.socket.emit(				"stations.remove",				this.stations[index]._id,				res => {					Toast.methods.addToast(res.message, 3000);				}			);		},		edit(station) {			this.editStation({				_id: station._id,				name: station.name,				type: station.type,				partyMode: station.partyMode,				description: station.description,				privacy: station.privacy,				displayName: station.displayName,				genres: station.genres,				blacklistedGenres: station.blacklistedGenres			});			this.openModal({				sector: "station",				modal: "editStation"			});		},		addGenre() {			const genre = document				.getElementById(`new-genre`)				.value.toLowerCase()				.trim();			if (this.newStation.genres.indexOf(genre) !== -1)				return Toast.methods.addToast("Genre already exists", 3000);			if (genre) {				this.newStation.genres.push(genre);				document.getElementById(`new-genre`).value = "";				return true;			}			return Toast.methods.addToast("Genre cannot be empty", 3000);		},		removeGenre(index) {			this.newStation.genres.splice(index, 1);		},		addBlacklistedGenre() {			const genre = document				.getElementById(`new-blacklisted-genre`)				.value.toLowerCase()				.trim();			if (this.newStation.blacklistedGenres.indexOf(genre) !== -1)				return Toast.methods.addToast("Genre already exists", 3000);			if (genre) {				this.newStation.blacklistedGenres.push(genre);				document.getElementById(`new-blacklisted-genre`).value = "";				return true;			}			return Toast.methods.addToast("Genre cannot be empty", 3000);		},		removeBlacklistedGenre(index) {			this.newStation.blacklistedGenres.splice(index, 1);		},		init() {			this.socket.emit("stations.index", data => {				this.stations = data.stations;			});			this.socket.emit("apis.joinAdminRoom", "stations", () => {});		},		...mapActions("modals", ["openModal"]),		...mapActions("admin/stations", ["editStation"])	},	mounted() {		io.getSocket(socket => {			this.socket = socket;			if (this.socket.connected) this.init();			this.socket.on("event:admin.station.added", station => {				this.stations.push(station);			});			this.socket.on("event:admin.station.removed", stationId => {				this.stations = this.stations.filter(station => {					return station._id !== stationId;				});			});			io.onConnect(() => {				this.init();			});		});	}};</script><style lang="scss" scoped>@import "styles/global.scss";.tag {	margin-top: 5px;	&:not(:last-child) {		margin-right: 5px;	}}td {	word-wrap: break-word;	max-width: 10vw;	vertical-align: middle;}.is-info:focus {	background-color: $primary-color;}.genre-wrapper {	display: flex;	justify-content: space-around;}.card-footer-item {	color: $primary-color;}</style>
 |