prerelease2
MarketplaceItem, Marketplace, Pagination, Update modal popup for new releases
This commit is contained in:
parent
4a173a4474
commit
51ac44116a
15 changed files with 550 additions and 38 deletions
|
@ -15,6 +15,7 @@
|
|||
"core-js": "^3.6.5",
|
||||
"crypto-random-string": "^3.3.0",
|
||||
"dotenv-webpack": "^6.0.0",
|
||||
"lodash.throttle": "^4.1.1",
|
||||
"socket.io": "^3.1.0",
|
||||
"to-boolean": "^1.0.0",
|
||||
"v-offline": "^1.3.0",
|
||||
|
@ -22,6 +23,7 @@
|
|||
"vue-axios": "^3.2.2",
|
||||
"vue-i18n": "^8.17.3",
|
||||
"vue-keypress": "^2.1.1",
|
||||
"vue-matomo": "^3.14.0-0",
|
||||
"vue-router": "^3.2.0",
|
||||
"vue-socket.io": "^3.0.10",
|
||||
"vuex": "^3.4.0"
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
<div id="router content-wrapper">
|
||||
<router-view/>
|
||||
</div>
|
||||
<br>
|
||||
<div id="footer">
|
||||
<Footer/>
|
||||
</div>
|
||||
|
@ -30,6 +29,11 @@ export default {
|
|||
Footer
|
||||
},
|
||||
mounted() {
|
||||
if(JSON.parse(
|
||||
localStorage.getItem('token'))) {
|
||||
this.$store.commit('setToken', JSON.parse(
|
||||
localStorage.getItem('token')))
|
||||
}
|
||||
if(JSON.parse(
|
||||
localStorage.getItem('wind404'))) {
|
||||
var wind = JSON.parse(
|
||||
|
|
|
@ -142,6 +142,34 @@
|
|||
</div>
|
||||
</form>
|
||||
</b-modal>
|
||||
<b-modal :active="updateModal" @update:active="value => updateModal = value" :width="640" scroll="keep">
|
||||
<form>
|
||||
<div class="modal-card" style="width: auto">
|
||||
<header class="modal-card-head">
|
||||
<p class="modal-card-title">{{$t('update.title')}}</p>
|
||||
<button
|
||||
type="button"
|
||||
class="delete"
|
||||
@click="registerModal = false"/>
|
||||
</header>
|
||||
<section class="modal-card-body has-text-centered">
|
||||
<h1 class="subtitle">What's new in {{$store.state.client.clientVersion}}?</h1>
|
||||
<ul>
|
||||
<li>Marketplace</li>
|
||||
<li>Pagination Component</li>
|
||||
<li>Fix crashing when token is null</li>
|
||||
<li>User list pagination</li>
|
||||
<li>Marketplace Item</li>
|
||||
</ul>
|
||||
</section>
|
||||
<footer class="modal-card-foot">
|
||||
<b-button
|
||||
:label="$t('close')"
|
||||
@click="updateDismissed" />
|
||||
</footer>
|
||||
</div>
|
||||
</form>
|
||||
</b-modal>
|
||||
<b-modal :active="registerModal" @update:active="value => registerModal = value" :width="640" scroll="keep">
|
||||
<form>
|
||||
<div class="modal-card" style="width: auto">
|
||||
|
@ -354,6 +382,7 @@ export default {
|
|||
showBanner: true,
|
||||
showOutdatedBanner: true,
|
||||
friendCount: 0,
|
||||
updateModal: false,
|
||||
settings: {
|
||||
tab: 0,
|
||||
general: {
|
||||
|
@ -513,6 +542,17 @@ export default {
|
|||
this.showBanner = true
|
||||
}
|
||||
},
|
||||
updateDismissed() {
|
||||
localStorage.setItem("update-" + this.$store.state.client.clientVersion, true)
|
||||
this.updateModal = false
|
||||
},
|
||||
showUpdate() {
|
||||
if(!localStorage.getItem("update-" + this.$store.state.client.clientVersion)) {
|
||||
this.updateModal = true
|
||||
} else {
|
||||
this.updateModal = false
|
||||
}
|
||||
},
|
||||
removeBannerId() {
|
||||
localStorage.setItem(this.$store.state.client.bannerId, true)
|
||||
this.$store.state.client.bannerEnabled = false
|
||||
|
@ -699,6 +739,7 @@ export default {
|
|||
this.loading = false
|
||||
})
|
||||
}
|
||||
this.showUpdate()
|
||||
}
|
||||
}
|
||||
</script>
|
66
src/components/Pagination.vue
Normal file
66
src/components/Pagination.vue
Normal file
|
@ -0,0 +1,66 @@
|
|||
<template>
|
||||
<div class='pagination'>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import throttle from 'lodash.throttle'
|
||||
|
||||
export default {
|
||||
name: 'Pagination',
|
||||
props: ['loading', 'query-selector', 'padding-bottom', 'padding-top', 'paginate'],
|
||||
computed: {
|
||||
element () {
|
||||
if(this.querySelector){
|
||||
return document.querySelector(this.querySelector);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onScroll: throttle(function () {
|
||||
let paddingBottom = this.paddingBottom || 300;
|
||||
let paddingTop = this.paddingTop || 150;
|
||||
|
||||
let scrollBottom, scrollTop;
|
||||
|
||||
//If already loading then do not fire
|
||||
if(this.loading) return;
|
||||
|
||||
if(this.element) {
|
||||
scrollBottom = Math.floor(
|
||||
this.element.scrollTop +
|
||||
this.element.getBoundingClientRect().height +
|
||||
paddingBottom -
|
||||
this.element.scrollHeight
|
||||
);
|
||||
|
||||
scrollTop = paddingTop - this.element.scrollTop;
|
||||
} else {
|
||||
scrollBottom =
|
||||
window.innerHeight + window.pageYOffset +
|
||||
paddingBottom -
|
||||
document.body.scrollHeight;
|
||||
|
||||
scrollTop = paddingTop - document.body.scrollTop;
|
||||
}
|
||||
|
||||
if(scrollBottom > 0) {
|
||||
if(this.paginate) {
|
||||
this.$emit('loadNext');
|
||||
}
|
||||
} else if(scrollTop > 0) {
|
||||
this.$emit('loadPrevious');
|
||||
}
|
||||
})
|
||||
},
|
||||
mounted () {
|
||||
(this.element || window).addEventListener('scroll', this.onScroll);
|
||||
},
|
||||
destroyed () {
|
||||
(this.element || window).removeEventListener('scroll', this.onScroll);
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -175,7 +175,8 @@
|
|||
"relationships": {
|
||||
"pending": "Cancel Friend Request",
|
||||
"notFriends": "Send Friend Request",
|
||||
"pendingCanAccept": "Accept Friend Request"
|
||||
"pendingCanAccept": "Accept Friend Request",
|
||||
"accepted": "Remove friend"
|
||||
},
|
||||
"modifyUser": {
|
||||
"title": "Modify User",
|
||||
|
@ -266,6 +267,25 @@
|
|||
"soon": "(SOON)"
|
||||
}
|
||||
},
|
||||
"marketplace": {
|
||||
"hats": "Hats",
|
||||
"faces": "Faces",
|
||||
"shirts": "Shirts",
|
||||
"pants": "Pants",
|
||||
"collections": "Collections",
|
||||
"moreInfo": "More info",
|
||||
"filter": "Filters",
|
||||
"search": "Search the Marketplace"
|
||||
},
|
||||
"update": {
|
||||
"title": "Changelog for new update"
|
||||
},
|
||||
"marketplaceItem": {
|
||||
"moreInfo": "Information and Stats",
|
||||
"price": "Price",
|
||||
"originalPrice": "Original Price",
|
||||
"creator": "The Creator"
|
||||
},
|
||||
"currency": "Koins",
|
||||
"close": "Close",
|
||||
"tos": "Terms of Service",
|
||||
|
|
|
@ -6,10 +6,16 @@ import Buefy, {Snackbar} from 'buefy'
|
|||
import axios from 'axios'
|
||||
import VueAxios from 'vue-axios'
|
||||
import i18n from './i18n'
|
||||
import moment from 'moment'
|
||||
Vue.use(VueAxios, axios)
|
||||
Vue.use(Buefy)
|
||||
Vue.config.productionTip = false
|
||||
Vue.prototype.$snackbar = Snackbar
|
||||
Vue.filter('formatDate', function(value) {
|
||||
if (value) {
|
||||
return moment(String(value)).format('hh:mm A, DD/MM/YYYY')
|
||||
}
|
||||
})
|
||||
new Vue({
|
||||
router,
|
||||
store,
|
||||
|
|
|
@ -77,6 +77,22 @@ const routes = [
|
|||
name: 'Roadmap',
|
||||
component: route('Roadmap')
|
||||
},
|
||||
{
|
||||
path: '/marketplace/',
|
||||
redirect: '/marketplace/HATS',
|
||||
name: 'Marketplace',
|
||||
component: route('Marketplace')
|
||||
},
|
||||
{
|
||||
path: '/marketplace/:category',
|
||||
name: 'Marketplace',
|
||||
component: route('Marketplace')
|
||||
},
|
||||
{
|
||||
path: '/m/:id',
|
||||
name: 'MarketplaceItem',
|
||||
component: route('MarketplaceItem')
|
||||
},
|
||||
{
|
||||
path: '/stats',
|
||||
name: 'Stats',
|
||||
|
|
|
@ -2,21 +2,13 @@ import Vue from 'vue'
|
|||
import Vuex from 'vuex'
|
||||
import tb from 'to-boolean';
|
||||
Vue.use(Vuex)
|
||||
if(JSON.parse(
|
||||
localStorage.getItem('token'))) {
|
||||
var token = JSON.parse(
|
||||
localStorage.getItem('token'))
|
||||
} else {
|
||||
// eslint-disable-next-line no-redeclare
|
||||
var token = ''
|
||||
}
|
||||
export default new Vuex.Store({
|
||||
state: {
|
||||
debug: tb(process.env.VUE_APP_STAGING),
|
||||
wind: false,
|
||||
enableBrokenRoutes: false,
|
||||
client: {
|
||||
clientVersion: '1.0.0-prerelease',
|
||||
clientVersion: '1.0.0-prerelease2',
|
||||
latestClientVersion: '',
|
||||
latestAPIVersion: '',
|
||||
bannerText: '',
|
||||
|
@ -48,7 +40,7 @@ export default new Vuex.Store({
|
|||
avatar: 'default',
|
||||
bot: '',
|
||||
system: '',
|
||||
token: token,
|
||||
token: '',
|
||||
koins: 0,
|
||||
emailVerified: false,
|
||||
modeler: false,
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
</p>
|
||||
</div>
|
||||
<div class="media-left">
|
||||
Created At: {{thread.createdAt}}
|
||||
Created At: {{thread.createdAt | formatDate()}}
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
@ -120,7 +120,6 @@ export default {
|
|||
},
|
||||
$route () {
|
||||
this.selectedCategory = this.$route.path.split('/')[2].toUpperCase()
|
||||
this.newThreads = 0
|
||||
this.getThreads(true)
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,5 +1,220 @@
|
|||
<template>
|
||||
<main>
|
||||
|
||||
<main class="section">
|
||||
<div class="column" style="float: left;">
|
||||
<nav class="panel">
|
||||
<p class="panel-heading">
|
||||
{{ $t('marketplace.filter') }} ({{category}})
|
||||
</p>
|
||||
<div class="panel-block">
|
||||
<p class="control has-icons-left">
|
||||
<b-input v-model="search" type="text" :placeholder="$t('marketplace.search')"></b-input>
|
||||
<span class="icon is-left">
|
||||
<i class="fas fa-search" aria-hidden="true"></i>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="tabs">
|
||||
<ul>
|
||||
<router-link tag="li" :to="'/marketplace/hats'" exact><a>{{ $t('marketplace.hats') }}</a></router-link>
|
||||
<router-link tag="li" :to="'/marketplace/faces'" exact><a>{{ $t('marketplace.faces') }}</a></router-link>
|
||||
<router-link tag="li" :to="'/marketplace/shirts'" exact><a>{{ $t('marketplace.shirts') }}</a></router-link>
|
||||
<router-link tag="li" :to="'/marketplace/pants'" exact><a>{{ $t('marketplace.pants') }}</a></router-link>
|
||||
<router-link tag="li" :to="'/marketplace/collections'" exact><a>{{ $t('marketplace.collections') }}</a></router-link>
|
||||
</ul>
|
||||
</div>
|
||||
<a class="panel-block">
|
||||
Recent
|
||||
</a>
|
||||
<a class="panel-block">
|
||||
Most popular
|
||||
</a>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="columns is-multiline" v-if="!loading">
|
||||
<div v-if="!items.length" class="column">
|
||||
<NoItems type="marketplace items">
|
||||
</NoItems>
|
||||
</div>
|
||||
<Pagination
|
||||
class='columns is-multiline'
|
||||
v-if='items.length'
|
||||
:loading='loading'
|
||||
:paginate="paginate"
|
||||
@loadNext='getItems(false)'
|
||||
>
|
||||
<div class="column is-3" style="float: left;" v-for='(item) in items' :key='"marketplace-" + item.id'>
|
||||
<router-link :to="'/m/' + item.id" class="subtitle">{{item.name}}</router-link>
|
||||
<div class="box">
|
||||
<img :src="'https://cdn.kaverti.com/marketplace/avatars/' + item.previewFile + '.png'" width="40%">
|
||||
<div class="buttons is-centered is-center">
|
||||
<b-button class="is-info" v-if="!item.saleEnabled">{{$t('user.inventoryTab.buyNow')}} <img style="vertical-align: middle" src="https://cdn.kaverti.com/icons/koins-white.svg" width="8%">{{item.price}}</b-button>
|
||||
<b-button class="is-success" v-if="item.saleEnabled">{{$t('user.inventoryTab.buyNow')}} <img style="vertical-align: middle" src="https://cdn.kaverti.com/icons/koins-white.svg" width="12%">{{item.salePrice}} <b-tooltip class="is-success" :label="$t('user.inventoryTab.onSale')"><i class="fas fa-info-circle"></i></b-tooltip></b-button>
|
||||
<b-button tag="router-link" :to="'/m/' + item.id" class="is-success">{{$t('marketplace.moreInfo')}}</b-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Pagination>
|
||||
</div>
|
||||
<div class="columns is-multiline" v-if="loading">
|
||||
<div class="column is-4">
|
||||
<div class="box">
|
||||
<h1 class="title">
|
||||
<b-skeleton></b-skeleton>
|
||||
</h1>
|
||||
<b-skeleton height="100px"></b-skeleton>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-4">
|
||||
<div class="box">
|
||||
<h1 class="title">
|
||||
<b-skeleton></b-skeleton>
|
||||
</h1>
|
||||
<b-skeleton height="100px"></b-skeleton>
|
||||
</div>
|
||||
</div> <div class="column is-4">
|
||||
<div class="box">
|
||||
<h1 class="title">
|
||||
<b-skeleton></b-skeleton>
|
||||
</h1>
|
||||
<b-skeleton height="100px"></b-skeleton>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-4">
|
||||
<div class="box">
|
||||
<h1 class="title">
|
||||
<b-skeleton></b-skeleton>
|
||||
</h1>
|
||||
<b-skeleton height="100px"></b-skeleton>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-4">
|
||||
<div class="box">
|
||||
<h1 class="title">
|
||||
<b-skeleton></b-skeleton>
|
||||
</h1>
|
||||
<b-skeleton height="100px"></b-skeleton>
|
||||
</div>
|
||||
</div> <div class="column is-4">
|
||||
<div class="box">
|
||||
<h1 class="title">
|
||||
<b-skeleton></b-skeleton>
|
||||
</h1>
|
||||
<b-skeleton height="100px"></b-skeleton>
|
||||
</div>
|
||||
</div> <div class="column is-4">
|
||||
<div class="box">
|
||||
<h1 class="title">
|
||||
<b-skeleton></b-skeleton>
|
||||
</h1>
|
||||
<b-skeleton height="100px"></b-skeleton>
|
||||
</div>
|
||||
</div> <div class="column is-4">
|
||||
<div class="box">
|
||||
<h1 class="title">
|
||||
<b-skeleton></b-skeleton>
|
||||
</h1>
|
||||
<b-skeleton height="100px"></b-skeleton>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-4">
|
||||
<div class="box">
|
||||
<h1 class="title">
|
||||
<b-skeleton></b-skeleton>
|
||||
</h1>
|
||||
<b-skeleton height="100px"></b-skeleton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
</main>
|
||||
</template>
|
||||
<script>
|
||||
import AjaxErrorHandler from "../../assets/js/errorHandler";
|
||||
import NoItems from "../components/NoItems"
|
||||
import Pagination from "../components/Pagination"
|
||||
export default {
|
||||
name: 'Marketplace',
|
||||
components: {
|
||||
NoItems,
|
||||
Pagination
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
items: [],
|
||||
last: [],
|
||||
search: '',
|
||||
limit: 30,
|
||||
loading: true,
|
||||
paginate: true,
|
||||
offset: 0,
|
||||
nextURL: null,
|
||||
category: this.$route.params.category
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
doSearch() {
|
||||
this.items = []
|
||||
this.loading = true
|
||||
this.offset = 0
|
||||
this.paginate = true
|
||||
this.axios
|
||||
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'marketplace/' + this.category + '?search=' + this.search + '&offset=' + this.offset)
|
||||
.then(res => {
|
||||
this.items = res.data.Items
|
||||
this.loading = false
|
||||
})
|
||||
.catch((e) => {
|
||||
this.loading = false
|
||||
AjaxErrorHandler(this.$store)(e)
|
||||
})
|
||||
},
|
||||
getItems (initial) {
|
||||
this.loading = true
|
||||
this.axios
|
||||
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'marketplace/' + this.category + '?offset=' + this.offset)
|
||||
.then(res => {
|
||||
if(res.data.length < this.limit) {
|
||||
this.offset = null;
|
||||
} else {
|
||||
this.offset+= this.limit;
|
||||
}
|
||||
if(!initial && !res.data.Items.length) {
|
||||
this.paginate = false
|
||||
}
|
||||
if(initial) {
|
||||
this.items = res.data.Items
|
||||
} else {
|
||||
this.items.push(...res.data.Items)
|
||||
this.last = []
|
||||
this.last = res.data.Items
|
||||
}
|
||||
this.loading = false
|
||||
})
|
||||
.catch((e) => {
|
||||
this.loading = false
|
||||
AjaxErrorHandler(this.$store)(e)
|
||||
})
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
search () {
|
||||
this.doSearch()
|
||||
},
|
||||
$route () {
|
||||
this.items = []
|
||||
this.offset = 0
|
||||
this.paginate = true
|
||||
this.category = this.$route.params.category
|
||||
this.getItems(true)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getItems(true)
|
||||
}
|
||||
}
|
||||
</script>
|
111
src/views/MarketplaceItem.vue
Normal file
111
src/views/MarketplaceItem.vue
Normal file
|
@ -0,0 +1,111 @@
|
|||
<template>
|
||||
<main>
|
||||
<div class="section">
|
||||
<div class="columns" v-if="loading">
|
||||
<div class="column is-4">
|
||||
<h1 class="title has-text-centered"><b-skeleton></b-skeleton></h1>
|
||||
<div class="box">
|
||||
<b-skeleton></b-skeleton>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-7">
|
||||
<h1 class="title has-text-centered"><b-skeleton></b-skeleton></h1>
|
||||
<div class="box has-text-right">
|
||||
<b-skeleton></b-skeleton>
|
||||
<b-skeleton></b-skeleton>
|
||||
<b-skeleton></b-skeleton>
|
||||
</div>
|
||||
<h1 class="title has-text-centered"><b-skeleton></b-skeleton></h1>
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
|
||||
<div class="content">
|
||||
<b-skeleton></b-skeleton>
|
||||
<b-skeleton></b-skeleton>
|
||||
<b-skeleton></b-skeleton>
|
||||
<b-skeleton></b-skeleton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="columns" v-if="!loading">
|
||||
<div class="column is-4">
|
||||
<h1 class="title has-text-centered">{{item.name}}</h1>
|
||||
<div class="box">
|
||||
<img :src="'https://cdn.kaverti.com/marketplace/avatars/' + item.previewFile + '.png'">
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-7">
|
||||
<h1 class="title has-text-centered">{{$t('marketplaceItem.moreInfo')}}</h1>
|
||||
<div class="box has-text-right">
|
||||
<b-button class="is-info" v-if="!item.saleEnabled && !purchased">Buy now</b-button>
|
||||
<b-button class="is-success" v-if="item.saleEnabled && !purchased">Buy now for discounted price</b-button>
|
||||
<b-button disabled v-if="purchased">You own this item!</b-button>
|
||||
<hr class="solid">
|
||||
<p v-if="item.saleEnabled">{{$t('marketplaceItem.price')}}: <img style="vertical-align: middle" src="https://cdn.kaverti.com/icons/koins.svg" width="5%">{{item.salePrice}}</p>
|
||||
<p v-if="item.saleEnabled">{{$t('marketplaceItem.originalPrice')}}: <img style="vertical-align: middle" src="https://cdn.kaverti.com/icons/koins.svg" width="5%">{{item.price}}</p>
|
||||
<p v-if="!item.saleEnabled">{{$t('marketplaceItem.price')}}: <img style="vertical-align: middle" src="https://cdn.kaverti.com/icons/koins.svg" width="5%">{{item.price}}</p>
|
||||
<p>Uploaded at: {{item.createdAt | formatDate()}}</p>
|
||||
</div>
|
||||
<h1 class="title has-text-centered">{{$t('marketplaceItem.creator')}}</h1>
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<div class="media">
|
||||
<div class="media-left">
|
||||
<figure class="image is-48x48">
|
||||
<img :src="'https://cdn.kaverti.com/user/avatars/headshot/default.png'" alt="Avatar Image">
|
||||
</figure>
|
||||
</div>
|
||||
<div class="media-content">
|
||||
<router-link :to="'/u/' + item.User.username" class="title">{{item.User.username}}</router-link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content" v-if="item.User.description">
|
||||
{{item.User.description}}
|
||||
</div>
|
||||
<div class="content" v-if="!item.User.description">
|
||||
{{$t('user.defaultDesc')}} {{item.User.username}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</template>
|
||||
<script>
|
||||
import AjaxErrorHandler from '../../assets/js/errorHandler'
|
||||
export default {
|
||||
name: 'MarketplaceItem',
|
||||
data() {
|
||||
return {
|
||||
modifyUserModal: true,
|
||||
loading: true,
|
||||
item: {
|
||||
name: "Loading",
|
||||
description: "Loading",
|
||||
price: 0,
|
||||
previewFile: 'loading',
|
||||
User: {
|
||||
username: 'Loading'
|
||||
},
|
||||
createdAt: "2020-01-01T00:00:00.000Z"
|
||||
},
|
||||
purchased: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.axios
|
||||
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + `/` + `marketplace/view/${this.$route.params.id}`)
|
||||
.then(res => this.item = res.data, this.loading = false)
|
||||
.catch((e) => {
|
||||
AjaxErrorHandler(this.$store)(e)
|
||||
})
|
||||
this.axios
|
||||
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + `/` + `marketplace/check/${this.$route.params.id}`)
|
||||
.then(res => this.purchased = res.data.purchased)
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -26,7 +26,7 @@
|
|||
<div class="box limit">
|
||||
<div v-if="user.description">{{ $t('user.description') }}: {{user.description}}</div><br>
|
||||
<div v-if="!user.description">{{$t('user.description')}}: {{$t('user.defaultDesc')}} {{user.username}}</div>
|
||||
{{ $t('user.created') }}: {{user.createdAt}}<br>
|
||||
{{ $t('user.created') }}: {{user.createdAt | formatDate()}}<br>
|
||||
{{ $t('user.marketplace') }}:
|
||||
</div>
|
||||
</div>
|
||||
|
@ -59,7 +59,7 @@
|
|||
import AjaxErrorHandler from '../../assets/js/errorHandler'
|
||||
import Badges from '../components/Badges'
|
||||
export default {
|
||||
name: 'user',
|
||||
name: 'User',
|
||||
components: {
|
||||
Badges
|
||||
},
|
||||
|
@ -313,7 +313,7 @@ export default {
|
|||
return selectedIndex
|
||||
}
|
||||
},
|
||||
created () {
|
||||
mounted () {
|
||||
this.resetFetchData()
|
||||
this.selected = this.getIndexFromRoute(this.$route.path)
|
||||
|
||||
|
|
|
@ -6,6 +6,14 @@
|
|||
<NoItems :connection="true" type="users">
|
||||
</NoItems>
|
||||
</div>
|
||||
<Pagination
|
||||
key='user-row'
|
||||
class='columns is-multiline'
|
||||
v-if='users.length'
|
||||
:loading='loading'
|
||||
:paginate="paginate"
|
||||
@loadNext='getUsers(false)'
|
||||
>
|
||||
<div class="column is-3" v-for='(user) in users' :key='"user-" + user.id'>
|
||||
<div class="box">
|
||||
<h1 class="title">{{user.username}} <Badges :username="user.username" :system="user.system" :hidden="user.hidden" :admin="user.admin" :booster="user.booster" :bot="user.bot"></Badges></h1>
|
||||
|
@ -13,6 +21,7 @@
|
|||
<b-button tag="router-link" :to='"/u/" + user.username' class="is-centered is-info">View Profile</b-button>
|
||||
</div>
|
||||
</div>
|
||||
</Pagination>
|
||||
</div>
|
||||
<div class="columns is-multiline" v-if="loading">
|
||||
<div class="column is-4">
|
||||
|
@ -90,37 +99,58 @@
|
|||
import AjaxErrorHandler from "../../assets/js/errorHandler";
|
||||
import Badges from "../components/Badges"
|
||||
import NoItems from "../components/NoItems"
|
||||
import Pagination from "../components/Pagination"
|
||||
export default {
|
||||
name: 'Users',
|
||||
components: {
|
||||
Badges,
|
||||
NoItems
|
||||
NoItems,
|
||||
Pagination
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
users: [],
|
||||
offset: 0,
|
||||
limit: 15,
|
||||
paginate: true,
|
||||
limit: 30,
|
||||
loading: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getUsers(initial) {
|
||||
if(initial) {
|
||||
this.users = []
|
||||
this.loading = true
|
||||
this.offset = 0
|
||||
this.paginate = true
|
||||
}
|
||||
this.axios
|
||||
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'user/' + '?offset=' + this.offset)
|
||||
.then(res => {
|
||||
if(res.data < this.limit) {
|
||||
this.offset = null;
|
||||
} else {
|
||||
this.offset+= this.limit;
|
||||
}
|
||||
if(!initial && !res.data.length) {
|
||||
this.paginate = false
|
||||
}
|
||||
if(initial) {
|
||||
this.users = res.data
|
||||
} else {
|
||||
this.users.push(...res.data)
|
||||
}
|
||||
this.loading = false
|
||||
})
|
||||
.catch((e) => {
|
||||
this.loading = false
|
||||
AjaxErrorHandler(this.$store)(e)
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.loading = true
|
||||
this.axios
|
||||
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + `/` + `user?offset=${this.offset};`)
|
||||
.then(res => {
|
||||
this.users.push(...res.data);
|
||||
if(res.data.length < this.limit) {
|
||||
this.offset = null;
|
||||
} else {
|
||||
this.offset+= this.limit;
|
||||
}
|
||||
this.loading = false
|
||||
})
|
||||
.catch(e => {
|
||||
AjaxErrorHandler(this.$store)(e)
|
||||
this.loading = false
|
||||
})
|
||||
this.getUsers()
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -1,7 +1,7 @@
|
|||
const Dotenv = require('dotenv-webpack');
|
||||
module.exports = {
|
||||
devServer: {
|
||||
proxy: 'http://localhost:23981'
|
||||
proxy: 'http://localhost:23982'
|
||||
},
|
||||
|
||||
publicPath: '/',
|
||||
|
|
10
yarn.lock
10
yarn.lock
|
@ -8234,6 +8234,11 @@ lodash.templatesettings@^4.0.0:
|
|||
dependencies:
|
||||
lodash._reinterpolate "^3.0.0"
|
||||
|
||||
lodash.throttle@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4"
|
||||
integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=
|
||||
|
||||
lodash.transform@^4.6.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.transform/-/lodash.transform-4.6.0.tgz#12306422f63324aed8483d3f38332b5f670547a0"
|
||||
|
@ -12671,6 +12676,11 @@ vue-loader@^15.9.2:
|
|||
vue-hot-reload-api "^2.3.0"
|
||||
vue-style-loader "^4.1.0"
|
||||
|
||||
vue-matomo@^3.14.0-0:
|
||||
version "3.14.0-0"
|
||||
resolved "https://registry.yarnpkg.com/vue-matomo/-/vue-matomo-3.14.0-0.tgz#f8e668c26ec1f2f7b4498f758edfb7c387259735"
|
||||
integrity sha512-i1IkZGSXNY84zg1gVU8TOuaqajYDWQYl4Vs7M1mEb21cNhlMZKUxxgElvj+xmv7ytYUc/6ekZbxIS+y6W4qTMQ==
|
||||
|
||||
vue-router@^3.2.0:
|
||||
version "3.4.9"
|
||||
resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.4.9.tgz#c016f42030ae2932f14e4748b39a1d9a0e250e66"
|
||||
|
|
Loading…
Reference in a new issue