Skip to content

Commit

Permalink
feat(Currency detail): New currency detail page (#1170)
Browse files Browse the repository at this point in the history
  • Loading branch information
raphodn authored Dec 25, 2024
1 parent 54a1035 commit 206b81f
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 3 deletions.
16 changes: 14 additions & 2 deletions src/components/CurrencyChip.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<v-chip label size="small" prepend-icon="mdi-cash" density="comfortable" :color="currencyMissingAndShowError ? 'error' : 'default'">
<v-chip label size="small" prepend-icon="mdi-cash" density="comfortable" :color="currencyMissingAndShowError ? 'error' : 'default'" @click="goToCurrency()">
<span v-if="currency">{{ currency }}</span>
<span v-else-if="currencyMissingAndShowError">
<i class="text-lowercase">{{ $t('Common.Currency') }}</i>
Expand All @@ -20,12 +20,24 @@ export default {
showErrorIfCurrencyMissing: {
type: Boolean,
default: false
}
},
readonly: {
type: Boolean,
default: false
},
},
computed: {
currencyMissingAndShowError() {
return !this.currency && this.showErrorIfCurrencyMissing
}
},
methods: {
goToCurrency() {
if (this.readonly || !this.currency) {
return
}
this.$router.push({ path: `/currencies/${this.currency}` })
},
}
}
</script>
2 changes: 1 addition & 1 deletion src/components/ProofFooterRow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<PriceCountChip v-if="!hidePriceCount" class="mr-1" :count="proof.price_count" :withLabel="true" @click="goToProof()" />
<LocationChip class="mr-1" :location="proof.location" :locationId="proof.location_id" :readonly="readonly" :showErrorIfLocationMissing="true" />
<DateChip class="mr-1" :date="proof.date" :showErrorIfDateMissing="true" :readonly="readonly" />
<CurrencyChip class="mr-1" :currency="proof.currency" :showErrorIfCurrencyMissing="true" />
<CurrencyChip class="mr-1" :currency="proof.currency" :showErrorIfCurrencyMissing="true" :readonly="readonly" />
<UserChip v-if="!hideProofOwner" class="mr-1" :username="proof.owner" :readonly="readonly" />
<RelativeDateTimeChip :dateTime="proof.created" />
</v-col>
Expand Down
1 change: 1 addition & 0 deletions src/router.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

111 changes: 111 additions & 0 deletions src/views/CurrencyDetail.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<template>
<v-row>
<v-col cols="12" sm="6">
<v-card :title="currency" prepend-icon="mdi-cash" data-name="currency-card" />
</v-col>
</v-row>

<v-row>
<v-col>
<h2 class="text-h6 d-inline mr-1">
{{ $t('Common.LatestPrices') }}
</h2>
<LoadedCountChip v-if="!loading" :loadedCount="currencyPriceList.length" :totalCount="currencyPriceTotal" />
<OrderMenu v-if="!loading" kind="price" :currentOrder="currentOrder" @upcurrency:currentOrder="selectPriceOrder($event)" />
</v-col>
</v-row>

<v-row class="mt-0">
<v-col v-for="price in currencyPriceList" :key="price" cols="12" sm="6" md="4" xl="3">
<PriceCard :price="price" :product="price.product" elevation="1" height="100%" />
</v-col>
</v-row>

<v-row v-if="loading">
<v-col align="center">
<v-progress-circular indeterminate :size="30" />
</v-col>
</v-row>
</template>

<script>
import { defineAsyncComponent } from 'vue'
import api from '../services/api'
import constants from '../constants'
import utils from '../utils.js'
export default {
components: {
LoadedCountChip: defineAsyncComponent(() => import('../components/LoadedCountChip.vue')),
OrderMenu: defineAsyncComponent(() => import('../components/OrderMenu.vue')),
PriceCard: defineAsyncComponent(() => import('../components/PriceCard.vue'))
},
data() {
return {
currency: this.$route.params.currency,
// data
currencyPriceList: [],
currencyPriceTotal: null,
currencyPricePage: 0,
loading: false,
// filter & order
currentOrder: constants.PRICE_ORDER_LIST[2].key, // date
}
},
computed: {
getPricesParams() {
let defaultParams = { currency: this.currency, order_by: this.currentOrder, page: this.currencyPricePage }
return defaultParams
},
},
watch: {
$route (newRoute, oldRoute) {
if (oldRoute && newRoute && newRoute.name == 'currency-detail' && oldRoute.fullPath != newRoute.fullPath) {
this.initCurrency()
}
}
},
mounted() {
this.currentOrder = this.$route.query[constants.ORDER_PARAM] || this.currentOrder
this.initCurrency()
// load more
this.handleDebouncedScroll = utils.debounce(this.handleScroll, 100)
window.addEventListener('scroll', this.handleDebouncedScroll)
},
unmounted() {
window.removeEventListener('scroll', this.handleDebouncedScroll)
},
methods: {
initCurrency() {
this.currency = this.$route.params.currency
this.currencyPriceList = []
this.currencyPriceTotal = null
this.currencyPricePage = 0
this.getCurrencyPrices()
},
getCurrencyPrices() {
if (this.currencyPriceTotal && (this.currencyPriceList.length >= this.currencyPriceTotal)) return
this.loading = true
this.currencyPricePage += 1
return api.getPrices(this.getPricesParams)
.then((data) => {
this.currencyPriceList.push(...data.items)
this.currencyPriceTotal = data.total
this.loading = false
})
},
selectPriceOrder(orderKey) {
if (this.currentOrder !== orderKey) {
this.currentOrder = orderKey
this.$router.push({ query: { ...this.$route.query, [constants.ORDER_PARAM]: this.currentOrder } })
// this.initCurrency() will be called in watch $route
}
},
handleScroll(event) { // eslint-disable-line no-unused-vars
if (utils.getDocumentScrollPercentage() > 90) {
this.getCurrencyPrices()
}
},
}
}
</script>

0 comments on commit 206b81f

Please sign in to comment.