kopia lustrzana https://github.com/manuelkasper/sotlas-frontend
rodzic
73b6f88f90
commit
b254f66a8f
|
@ -1,11 +1,13 @@
|
|||
<template>
|
||||
<b-dropdown v-if="authenticated" position="is-bottom-left" aria-role="menu">
|
||||
<a class="navbar-item callsign" slot="trigger" role="button"><span>{{ $keycloak.tokenParsed.callsign ? $keycloak.tokenParsed.callsign : $keycloak.userName }}</span><b-icon icon="angle-down"></b-icon></a>
|
||||
<template #trigger="{ active }">
|
||||
<b-button class="callsign" :icon-right="active ? 'angle-up' : 'angle-down'" :label="$keycloak.tokenParsed.callsign ? $keycloak.tokenParsed.callsign : $keycloak.userName"></b-button>
|
||||
</template>
|
||||
<b-dropdown-item v-if="$keycloak.tokenParsed.callsign" has-link><router-link :to="'/activators/' + $keycloak.tokenParsed.callsign" @click.native="$emit('linkClicked')">My activator page</router-link></b-dropdown-item>
|
||||
<b-dropdown-item @click="doAccountManagement">Manage account</b-dropdown-item>
|
||||
<b-dropdown-item @click="doLogout">Logout</b-dropdown-item>
|
||||
</b-dropdown>
|
||||
<div v-else class="navbar-item">
|
||||
<div v-else>
|
||||
<b-button type="is-info" @click="doLogin">Login</b-button>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -55,7 +57,4 @@ export default {
|
|||
.callsign {
|
||||
font-weight: bold;
|
||||
}
|
||||
.dropdown-trigger .icon {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,34 +1,30 @@
|
|||
<template>
|
||||
<nav class="navbar is-fixed-top">
|
||||
<div class="container">
|
||||
<div class="navbar-brand">
|
||||
<div class="navbar-item">
|
||||
<router-link to="/about"><img src="../assets/sotlas.svg" alt="Logo"></router-link>
|
||||
</div>
|
||||
<div class="navbar-item clock">
|
||||
<font-awesome-icon :icon="['far', 'clock']" class="faicon" /> {{ clock }}
|
||||
</div>
|
||||
<a role="button" :class="{ 'navbar-burger': true, 'burger': true, 'is-active': burgerActive }" aria-label="menu" aria-expanded="false" data-target="navbarMenu" @click="burgerClicked">
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
</a>
|
||||
</div>
|
||||
<div id="navbarMenu" :class="{ 'navbar-menu': true, 'is-active': burgerActive }">
|
||||
<div class="navbar-end">
|
||||
<div class="navbar-item">
|
||||
<SearchField :query="query" @search="closeBurger" />
|
||||
</div>
|
||||
<router-link v-for="link in links" :key="link.target" :to="link.target" :class="linkClass(link)" :title="link.title" @click.native="closeBurger">
|
||||
<b-icon v-if="link.icon" :pack="link.iconPack" :icon="link.icon" />
|
||||
{{ link.text }}
|
||||
<span v-if="!$mq.desktop">{{ link.mobileText }}</span>
|
||||
</router-link>
|
||||
<LoginButton @linkClicked="closeBurger" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<b-navbar wrapper-class="container" :fixed-top="true" :active.sync="burgerActive">
|
||||
<template #brand>
|
||||
<b-navbar-item tag="router-link" to="/about"><img src="../assets/sotlas.svg" alt="Logo"></b-navbar-item>
|
||||
<b-navbar-item class="clock" tag="div">
|
||||
<font-awesome-icon :icon="['far', 'clock']" class="faicon" /> {{ clock }}
|
||||
</b-navbar-item>
|
||||
</template>
|
||||
<template #end>
|
||||
<b-navbar-item tag="div">
|
||||
<SearchField :query="query" @search="closeBurger" />
|
||||
</b-navbar-item>
|
||||
<b-navbar-item v-for="link in links" tag="router-link" :key="link.target" :to="link.target" :title="link.title" @click.native="closeBurger">
|
||||
<b-icon v-if="link.icon" :pack="link.iconPack" :icon="link.icon" />
|
||||
{{ link.text }}
|
||||
</b-navbar-item>
|
||||
<b-navbar-dropdown label="More">
|
||||
<b-navbar-item v-for="link in moreLinks" tag="router-link" :key="link.target" :to="link.target" :title="link.title" @click.native="closeBurger">
|
||||
<b-icon v-if="link.icon" :pack="link.iconPack" :icon="link.icon" />
|
||||
{{ link.text }}
|
||||
</b-navbar-item>
|
||||
</b-navbar-dropdown>
|
||||
<b-navbar-item tag="div">
|
||||
<LoginButton @linkClicked="closeBurger" />
|
||||
</b-navbar-item>
|
||||
</template>
|
||||
</b-navbar>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -65,16 +61,6 @@ export default {
|
|||
clearInterval(this.clockInterval)
|
||||
},
|
||||
methods: {
|
||||
linkClass (link) {
|
||||
let classes = { 'navbar-item': true }
|
||||
if (this.$route.path.startsWith(link.target)) {
|
||||
classes['is-active'] = true
|
||||
}
|
||||
return classes
|
||||
},
|
||||
burgerClicked () {
|
||||
this.burgerActive = !this.burgerActive
|
||||
},
|
||||
closeBurger () {
|
||||
this.burgerActive = false
|
||||
},
|
||||
|
@ -107,6 +93,14 @@ export default {
|
|||
{
|
||||
target: '/alerts',
|
||||
text: 'Alerts'
|
||||
}
|
||||
]
|
||||
},
|
||||
moreLinks () {
|
||||
return [
|
||||
{
|
||||
target: '/new_photos',
|
||||
text: 'New Photos'
|
||||
},
|
||||
{
|
||||
target: '/activators',
|
||||
|
@ -114,7 +108,7 @@ export default {
|
|||
},
|
||||
{
|
||||
target: '/settings',
|
||||
mobileText: 'Settings',
|
||||
text: 'Settings',
|
||||
title: 'Settings',
|
||||
icon: 'cog',
|
||||
iconPack: 'fas'
|
||||
|
@ -151,9 +145,13 @@ export default {
|
|||
font-size: 1rem !important;
|
||||
}
|
||||
}
|
||||
a.navbar-item.is-active:not(:focus):not(:hover), .navbar-link.is-active:not(:focus):not(:hover) {
|
||||
.router-link-active:not(:focus):not(:hover) {
|
||||
background-color: whitesmoke;
|
||||
}
|
||||
.navbar-item .icon {
|
||||
margin-right: 0.25em !important;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.clock {
|
||||
opacity: 0.7;
|
||||
font-size: 1rem;
|
||||
|
@ -161,10 +159,4 @@ a.navbar-item.is-active:not(:focus):not(:hover), .navbar-link.is-active:not(:foc
|
|||
.clock .faicon {
|
||||
margin-right: 0.3em;
|
||||
}
|
||||
.navbar-brand .navbar-item {
|
||||
line-height: 1;
|
||||
}
|
||||
.navbar-menu .navbar-item span {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<file-pond name="photo" ref="filePond" :label-idle="labelIdle" :allow-multiple="true" :allow-replace="false" :allow-revert="false" :allow-paste="false" accepted-file-types="image/jpeg, image/png, image/heic" :server="uploadServer()" @processfile="onProcessFile" />
|
||||
<file-pond name="photo" ref="filePond" class-name="box" :label-idle="labelIdle" :allow-multiple="true" :allow-replace="false" :allow-revert="false" :allow-paste="false" accepted-file-types="image/jpeg, image/png, image/heic" :server="uploadServer()" @processfile="onProcessFile" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -92,6 +92,6 @@ export default {
|
|||
margin-bottom: 0;
|
||||
}
|
||||
>>> .filepond--panel-root {
|
||||
background-color: #f7f7f7;
|
||||
background-color: #f7f7f7;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,7 +1,16 @@
|
|||
<template>
|
||||
<div>
|
||||
<div v-for="group in groups" :key="group.key">
|
||||
<SummitPhotosGroup ref="photosGroup" :photos="group.photos" :title="group.title" :titleLink="group.titleLink" :summit="summit" @editPhoto="onEditPhoto" @deletePhoto="onDeletePhoto" @reorderPhotos="onReorderPhotos" />
|
||||
<SummitPhotosGroup ref="photosGroup" :photos="group.photos" :title="group.title" :titleLink="group.titleLink" :summit="summit" :editable="editable" :showSummitName="showSummitName" :showWaypointButton="showWaypointButton" @editPhoto="onEditPhoto" @deletePhoto="onDeletePhoto" @reorderPhotos="onReorderPhotos">
|
||||
<template v-slot:title>
|
||||
<template v-if="showSummitName">
|
||||
<router-link :to="group.titleLink">{{ group.title }}</router-link><span class="has-text-weight-normal"> on </span><router-link :to="'/summits/' + summit.code">{{ summit.name }} <span class="has-text-weight-normal">(<AltitudeLabel :altitude="summit.altitude" />, {{ summit.code }})</span></router-link>
|
||||
</template>
|
||||
<template v-else>
|
||||
<router-link :to="group.titleLink">{{ group.title }}</router-link>
|
||||
</template>
|
||||
</template>
|
||||
</SummitPhotosGroup>
|
||||
</div>
|
||||
<b-modal :active.sync="isEditorActive" has-modal-card trap-focus aria-role="dialog" aria-modal>
|
||||
<EditPhoto v-if="editingPhoto" :photo="editingPhoto" :summitCode="summit.code" @photoEdited="$emit('photoEdited')" />
|
||||
|
@ -12,6 +21,7 @@
|
|||
<script>
|
||||
import SummitPhotosGroup from './SummitPhotosGroup.vue'
|
||||
import EditPhoto from './EditPhoto.vue'
|
||||
import AltitudeLabel from './AltitudeLabel.vue'
|
||||
import utils from '../mixins/utils.js'
|
||||
import api from '../mixins/api.js'
|
||||
import moment from 'moment'
|
||||
|
@ -19,10 +29,14 @@ import moment from 'moment'
|
|||
export default {
|
||||
name: 'SummitPhotos',
|
||||
props: {
|
||||
summit: Object
|
||||
summit: Object,
|
||||
minDate: Date,
|
||||
editable: Boolean,
|
||||
showSummitName: Boolean,
|
||||
showWaypointButton: Boolean
|
||||
},
|
||||
components: {
|
||||
SummitPhotosGroup, EditPhoto
|
||||
SummitPhotosGroup, EditPhoto, AltitudeLabel
|
||||
},
|
||||
mixins: [utils, api],
|
||||
computed: {
|
||||
|
@ -33,7 +47,13 @@ export default {
|
|||
|
||||
// Group photos by author
|
||||
let authorGroups = new Map()
|
||||
this.summit.photos.forEach(photo => {
|
||||
let summitPhotos = this.summit.photos
|
||||
if (this.minDate) {
|
||||
summitPhotos = summitPhotos.filter(photo => {
|
||||
return moment(photo.uploadDate).isSameOrAfter(moment(this.minDate))
|
||||
})
|
||||
}
|
||||
summitPhotos.forEach(photo => {
|
||||
let authorGroup = authorGroups.get(photo.author)
|
||||
if (!authorGroup) {
|
||||
authorGroup = {
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
<template>
|
||||
<div class="photo-group">
|
||||
<div class="photo-group box">
|
||||
<div class="photo-group-title">
|
||||
<router-link v-if="titleLink" :to="titleLink">{{ title }}</router-link>
|
||||
<span v-else>{{ title }}</span>
|
||||
<slot name="title"></slot>
|
||||
</div>
|
||||
<PictureSwipe ref="pictureSwipe" class="photos" :items="swipeItems" :options="swipeOptions" @mouseoverPicture="mouseoverPicture" @mouseleavePicture="mouseleavePicture" @editPicture="onEditPicture" @deletePicture="onDeletePicture" @movePicture="onMovePicture" />
|
||||
<b-button v-if="waypointPhotos.length > 0 && !$mq.mobile" class="waypoints-button" icon-left="file-download" size="is-small" @click="downloadWaypoints">Photo waypoints (.gpx)</b-button>
|
||||
<b-button v-if="waypointPhotos.length > 0 && !$mq.mobile && showWaypointButton" class="waypoints-button" icon-left="file-download" size="is-small" @click="downloadWaypoints">Photo waypoints (.gpx)</b-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -20,9 +19,10 @@ export default {
|
|||
name: 'SummitPhotosGroup',
|
||||
props: {
|
||||
photos: Array,
|
||||
title: String,
|
||||
titleLink: String,
|
||||
summit: Object
|
||||
summit: Object,
|
||||
editable: Boolean,
|
||||
showSummitName: Boolean,
|
||||
showWaypointButton: Boolean
|
||||
},
|
||||
components: {
|
||||
PictureSwipe
|
||||
|
@ -51,7 +51,7 @@ export default {
|
|||
h: largeH,
|
||||
title: this.makeTitleHtml(photo),
|
||||
thumbTitle: photo.title,
|
||||
editable: (this.$keycloak && this.$keycloak.authenticated && this.$keycloak.tokenParsed.callsign === photo.author),
|
||||
editable: (this.editable && this.$keycloak && this.$keycloak.authenticated && this.$keycloak.tokenParsed.callsign === photo.author),
|
||||
filename: photo.filename
|
||||
}
|
||||
})
|
||||
|
@ -172,14 +172,6 @@ export default {
|
|||
max-height: 128px;
|
||||
max-width: 256px;
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
.photos >>> figure {
|
||||
margin: 0 0.5rem 0.5rem 0;
|
||||
}
|
||||
.photos >>> figure img {
|
||||
max-height: 104px;
|
||||
}
|
||||
}
|
||||
>>> .photo-title {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
@ -206,7 +198,19 @@ export default {
|
|||
.photo-group-title a:hover {
|
||||
color: #3273dc;
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
.photos >>> figure {
|
||||
margin: 0 0.5rem 0.5rem 0;
|
||||
}
|
||||
.photos >>> figure img {
|
||||
max-height: 104px;
|
||||
}
|
||||
.photo-group {
|
||||
padding: 0.25rem 0 0 0.5rem;
|
||||
}
|
||||
}
|
||||
.waypoints-button {
|
||||
margin-bottom: 0.75rem;
|
||||
margin-right: 0.75rem;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -9,7 +9,7 @@ import MatchMedia from 'vue-match-media/src'
|
|||
import VueKeyCloak from '@dsb-norge/vue-keycloak-js'
|
||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||
import { faCheck, faCheckCircle, faInfoCircle, faExclamationTriangle, faExclamationCircle, faArrowUp, faPlus, faCheckDouble,
|
||||
faAngleRight, faAngleLeft, faAngleDown, faEye, faEyeSlash, faCaretUp, faUpload, faLink, faHistory, faThList, faImages,
|
||||
faAngleRight, faAngleLeft, faAngleDown, faAngleUp, faEye, faEyeSlash, faCaretUp, faUpload, faLink, faHistory, faThList, faImages,
|
||||
faQuoteRight, faSearch, faMountains, faUser, faClock, faChevronCircleUp, faChevronCircleDown, faChartBar, faFileDownload,
|
||||
faExchange, faGlobe, faCalendarDay, faTrashAlt, faEdit, faClone, faCheckCircle as farCheckCircle, faArrowsH, faArrowsAlt,
|
||||
faSnowflake, faWindowMinimize, faWindowMaximize, faWindowClose, faExpandArrows, faLocation, faCalendarCheck, faComment, faSpinner,
|
||||
|
@ -24,7 +24,7 @@ import axios from 'axios'
|
|||
import { SnackbarProgrammatic as Snackbar } from 'buefy/dist/components/snackbar'
|
||||
|
||||
library.add(faCheck, faCheckCircle, faInfoCircle, faExclamationTriangle, faExclamationCircle, faArrowUp, faPlus, faCheckDouble,
|
||||
faAngleRight, faAngleLeft, faAngleDown, faEye, faEyeSlash, faCaretUp, faUpload, faLink, faHistory, faThList, faImages,
|
||||
faAngleRight, faAngleLeft, faAngleDown, faAngleUp, faEye, faEyeSlash, faCaretUp, faUpload, faLink, faHistory, faThList, faImages,
|
||||
faQuoteRight, faSearch, faMountains, faUser, faClock, faChevronCircleUp, faChevronCircleDown, faMap, faChartBar, faFileDownload,
|
||||
faExchange, faGlobe, faCalendarDay, faTrashAlt, faEdit, faClone, farCheckCircle, faArrowsH, faArrowsAlt,
|
||||
faSnowflake, faWindowMinimize, faWindowMaximize, faWindowClose, faExpandArrows, faLocation, faCalendarCheck, faComment, faSpinner,
|
||||
|
|
|
@ -16,6 +16,7 @@ import Spots from './views/Spots.vue'
|
|||
import SotaSpots from './views/SotaSpots.vue'
|
||||
import RBNSpots from './views/RBNSpots.vue'
|
||||
import Alerts from './views/Alerts.vue'
|
||||
import NewPhotos from './views/NewPhotos.vue'
|
||||
|
||||
Vue.use(Router)
|
||||
|
||||
|
@ -162,6 +163,10 @@ let router = new Router({
|
|||
path: '/alerts',
|
||||
component: Alerts
|
||||
},
|
||||
{
|
||||
path: '/new_photos',
|
||||
component: NewPhotos
|
||||
},
|
||||
{
|
||||
path: '*',
|
||||
component: NotFound,
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
<template>
|
||||
<PageLayout>
|
||||
<template v-slot:title>New Photos</template>
|
||||
<template v-slot:title-right>
|
||||
<b-field>
|
||||
<b-dropdown class="control" v-model="selectedAssociations" multiple aria-role="list" :scrollable="$mq.desktop" @change="loadNewPhotos">
|
||||
<b-button icon-right="angle-down" slot="trigger">
|
||||
Associations {{ selectedAssociations.length > 0 ? ('(' + selectedAssociations.length + ')') : '' }}
|
||||
</b-button>
|
||||
<b-dropdown-item v-for="association in associations" :key="association.code" :value="association.code" aria-role="listitem">
|
||||
{{ association.code }} – {{ association.name }}
|
||||
</b-dropdown-item>
|
||||
</b-dropdown>
|
||||
</b-field>
|
||||
</template>
|
||||
<template>
|
||||
<section v-if="summits !== null && summits.length > 0" class="section">
|
||||
<div class="container">
|
||||
<SummitPhotos v-for="summit in summits" class="inline" :key="summit.code" :summit="summit" :minDate="minDate" :showSummitName="true" />
|
||||
</div>
|
||||
</section>
|
||||
<section v-else-if="summits != null" class="section">
|
||||
<div class="container">
|
||||
<b-message type="is-info" has-icon>
|
||||
No recently uploaded photos for summits in the selected associations.
|
||||
</b-message>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
</PageLayout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from 'axios'
|
||||
import moment from 'moment'
|
||||
import prefs from '../mixins/prefs.js'
|
||||
import utils from '../mixins/utils.js'
|
||||
|
||||
import PageLayout from '../components/PageLayout.vue'
|
||||
import SummitPhotos from '../components/SummitPhotos.vue'
|
||||
|
||||
export default {
|
||||
name: 'NewPhotos',
|
||||
components: { PageLayout, SummitPhotos },
|
||||
mixins: [prefs, utils],
|
||||
prefs: {
|
||||
key: 'newPhotosPrefs',
|
||||
props: ['selectedAssociations']
|
||||
},
|
||||
methods: {
|
||||
loadNewPhotos () {
|
||||
this.loadingComponent = this.$buefy.loading.open({ canCancel: true })
|
||||
|
||||
let recentPhotosParams = { limit: this.limit }
|
||||
let associations = '*'
|
||||
if (this.selectedAssociations.length > 0) {
|
||||
associations = this.selectedAssociations.join('|')
|
||||
}
|
||||
axios.get('https://api.sotl.as/summits/recent_photos/' + associations + '/' + this.days, { params: recentPhotosParams })
|
||||
.then(response => {
|
||||
this.loadingComponent.close()
|
||||
this.summits = response.data
|
||||
})
|
||||
},
|
||||
loadAssociations () {
|
||||
axios.get('https://api.sotl.as/associations/all')
|
||||
.then(response => {
|
||||
this.associations = response.data
|
||||
})
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
minDate () {
|
||||
return moment().subtract(this.days, 'days').toDate()
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
document.title = 'New Photos - SOTLAS'
|
||||
|
||||
this.loadAssociations()
|
||||
this.loadNewPhotos()
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
summits: null,
|
||||
days: 7,
|
||||
limit: 20,
|
||||
associations: null,
|
||||
selectedAssociations: []
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.dropdown + .dropdown {
|
||||
margin-left: 0;
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
.dropdown-item {
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
.inline {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
>>> .photo-group {
|
||||
margin-right: 0.75rem;
|
||||
}
|
||||
</style>
|
|
@ -3,61 +3,61 @@
|
|||
<template v-slot:title>Search results</template>
|
||||
<template>
|
||||
<section v-if="summits !== null && summits.length > 0" class="section">
|
||||
<div class="container">
|
||||
<h4 class="title is-4"><b-icon icon="mountains" />Summits</h4>
|
||||
<b-field v-if="inactiveCount > 0" grouped>
|
||||
<b-switch v-model="showInactive">Show inactive ({{ inactiveCount }})</b-switch>
|
||||
</b-field>
|
||||
<div class="container">
|
||||
<h4 class="title is-4"><b-icon icon="mountains" />Summits</h4>
|
||||
<b-field v-if="inactiveCount > 0" grouped>
|
||||
<b-switch v-model="showInactive">Show inactive ({{ inactiveCount }})</b-switch>
|
||||
</b-field>
|
||||
|
||||
<SummitList :data="filteredSummits" auto-width />
|
||||
<SummitList :data="filteredSummits" auto-width />
|
||||
|
||||
<b-message v-if="summits !== null && summits.length === this.limit" type="is-warning" has-icon>
|
||||
More than {{ this.limit }} summits found, so not all summits may be shown. Please make your search input more specific.
|
||||
</b-message>
|
||||
</div>
|
||||
</section>
|
||||
<b-message v-if="summits !== null && summits.length === this.limit" type="is-warning" has-icon>
|
||||
More than {{ this.limit }} summits found, so not all summits may be shown. Please make your search input more specific.
|
||||
</b-message>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section v-if="activators !== null && activators.length > 0" class="section">
|
||||
<div class="container">
|
||||
<h4 class="title is-4"><b-icon icon="user" />Activators</h4>
|
||||
<section v-if="activators !== null && activators.length > 0" class="section">
|
||||
<div class="container">
|
||||
<h4 class="title is-4"><b-icon icon="user" />Activators</h4>
|
||||
|
||||
<b-table class="auto-width" default-sort="callsign" :narrowed="true" :striped="true" :data="activators" :mobile-cards="false">
|
||||
<template slot-scope="props">
|
||||
<b-table-column field="callsign" label="Callsign" sortable>
|
||||
<router-link :to="makeActivatorLink(props.row.callsign)">{{ props.row.callsign }}</router-link>
|
||||
</b-table-column>
|
||||
<b-table-column field="summits" label="Summits" numeric sortable>
|
||||
{{ props.row.summits }}
|
||||
</b-table-column>
|
||||
<b-table-column field="points" :label="$mq.mobile ? 'Pts.' : 'Points'" numeric sortable>
|
||||
{{ props.row.points }}
|
||||
</b-table-column>
|
||||
<b-table-column field="bonusPoints" :label="$mq.mobile ? 'Bonus' : 'Bonus points'" numeric sortable>
|
||||
{{ props.row.bonusPoints }}
|
||||
</b-table-column>
|
||||
<b-table-column field="score" label="Score" numeric sortable>
|
||||
{{ props.row.score }}
|
||||
</b-table-column>
|
||||
<b-table-column v-if="!$mq.mobile" field="avgPoints" label="Avg. points" numeric sortable>
|
||||
{{ props.row.avgPoints }}
|
||||
</b-table-column>
|
||||
</template>
|
||||
</b-table>
|
||||
<b-table class="auto-width" default-sort="callsign" :narrowed="true" :striped="true" :data="activators" :mobile-cards="false">
|
||||
<template slot-scope="props">
|
||||
<b-table-column field="callsign" label="Callsign" sortable>
|
||||
<router-link :to="makeActivatorLink(props.row.callsign)">{{ props.row.callsign }}</router-link>
|
||||
</b-table-column>
|
||||
<b-table-column field="summits" label="Summits" numeric sortable>
|
||||
{{ props.row.summits }}
|
||||
</b-table-column>
|
||||
<b-table-column field="points" :label="$mq.mobile ? 'Pts.' : 'Points'" numeric sortable>
|
||||
{{ props.row.points }}
|
||||
</b-table-column>
|
||||
<b-table-column field="bonusPoints" :label="$mq.mobile ? 'Bonus' : 'Bonus points'" numeric sortable>
|
||||
{{ props.row.bonusPoints }}
|
||||
</b-table-column>
|
||||
<b-table-column field="score" label="Score" numeric sortable>
|
||||
{{ props.row.score }}
|
||||
</b-table-column>
|
||||
<b-table-column v-if="!$mq.mobile" field="avgPoints" label="Avg. points" numeric sortable>
|
||||
{{ props.row.avgPoints }}
|
||||
</b-table-column>
|
||||
</template>
|
||||
</b-table>
|
||||
|
||||
<b-message v-if="activators !== null && activators.length === this.limit" type="is-warning" has-icon>
|
||||
More than {{ this.limit }} activators found, so not all activators may be shown. Please make your search input more specific.
|
||||
</b-message>
|
||||
</div>
|
||||
</section>
|
||||
<b-message v-if="activators !== null && activators.length === this.limit" type="is-warning" has-icon>
|
||||
More than {{ this.limit }} activators found, so not all activators may be shown. Please make your search input more specific.
|
||||
</b-message>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<b-message v-if="activators !== null && activators.length === 0 && summits !== null && summits.length === 0" type="is-info" has-icon>
|
||||
No matching summits or activators for '{{ $route.query.q }}' found.
|
||||
</b-message>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<b-message v-if="activators !== null && activators.length === 0 && summits !== null && summits.length === 0" type="is-info" has-icon>
|
||||
No matching summits or activators for '{{ $route.query.q }}' found.
|
||||
</b-message>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
</PageLayout>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -95,10 +95,10 @@
|
|||
<section v-if="summit" class="section">
|
||||
<div class="container">
|
||||
<h4 class="title is-4">Photos</h4>
|
||||
<SummitPhotos ref="summitPhotos" :summit="summit" @photoDeleted="reloadPhotos" @photoEdited="reloadPhotos" @photosReordered="reloadPhotos" />
|
||||
<SummitPhotos ref="summitPhotos" :summit="summit" :editable="true" :showWaypointButton="true" @photoDeleted="reloadPhotos" @photoEdited="reloadPhotos" @photosReordered="reloadPhotos" />
|
||||
|
||||
<PhotosUploader v-if="$keycloak && $keycloak.authenticated" :summitCode="summitCode" @upload="reloadPhotos" />
|
||||
<div v-else class="uploader-placeholder"><font-awesome-icon :icon="['far', 'images']" size="lg" /> Log in and upload your photos of this summit!</div>
|
||||
<div v-else class="uploader-placeholder box"><font-awesome-icon :icon="['far', 'images']" size="lg" /> Log in and upload your photos of this summit!</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue