Skip to content

Commit

Permalink
feat(report): implemented report page
Browse files Browse the repository at this point in the history
  • Loading branch information
GalvinGao committed Aug 13, 2019
1 parent 5a9a381 commit 646e197
Show file tree
Hide file tree
Showing 9 changed files with 309 additions and 158 deletions.
15 changes: 10 additions & 5 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
</v-card>
</v-dialog>
<v-dialog
v-model="$store.state.ajaxLoading"
v-model="prefetchingResources"
persistent
width="300"
>
Expand Down Expand Up @@ -285,13 +285,14 @@ export default {
localizations: [{
id: 'zh_CN',
name: '简体中文'
}, {
id: 'zh_TW',
name: '繁体中文'
}, {
id: 'en',
name: 'English'
}, {
id: 'jp',
name: '日本語'
}],
prefetchingResources: false,
drawer: true,
dark: true,
nowBuildNoticeNotClosed: true
Expand Down Expand Up @@ -324,7 +325,8 @@ export default {
: "https://penguin-stats.s3-ap-southeast-1.amazonaws.com/penguin_stats_logo_croissant.png"
},
fetchData () {
let startAjaxAt = new Date().getTime()
this.prefetchingResources = true;
let startAjaxAt = new Date().getTime();
axios.all([
service.get("/items"),
service.get("/limitations"),
Expand All @@ -345,6 +347,9 @@ export default {
.catch((err) => {
console.log(err)
})
.finally(() => {
this.prefetchingResources = false
})
},
changeLocale (localeId) {
this.$i18n.locale = localeId
Expand Down
13 changes: 13 additions & 0 deletions src/apis/report.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import service from '@/utils/service'
import config from '@/config'

export default {
async submitReport({stageId, drops, furnitureNum}) {
return service.post("/report", {
drops,
furnitureNum,
stageId,
...config.api.submitParams
})
}
}
200 changes: 128 additions & 72 deletions src/components/ItemStepper.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,61 @@
{
"zh": {
"rules": {
"required": ""
"gte": "“{item}” 应多于或等于 {quantity}",
"lte": "“{item}” 应少于或等于 {quantity}",
"not": "“{item}” 的数量应不等于 {quantity}",
"natural": "数量值应为自然数"
}
},
"en": {
"rules": {
"gte": "Quantity of \"{item}\" should ≥ {quantity}",
"lte": "Quantity of \"{item}\" should ≤ {quantity}",
"not": "Quantity of \"{item}\" should ≠ {quantity}",
"natural": "Value of quantity should be a natural number"
}
}
}
</i18n>

<template>
<v-flex
class="itemStepper pa-3 ma-2"
style="display: inline-block"
>
<h5 class="title mb-3">
{{ demoItem.name }}
</h5>
<v-text-field
label="数量"
type="number"
<v-text-field
ref="quantityInput"
v-model="quantity"

label="数量"
type="number"

outline
:rules="[rules.required, rules.number]"
outline

:value="0"
:rules="validationRules"
append-icon="mdi-minus"
:disabled="disable.actual"

append-icon="mdi-minus"
prepend-inner-icon="mdi-plus"
prepend-inner-icon="mdi-plus"
style="display: inline-flex"

style="display: inline-flex"
@click:append-outer="reduction"
@click:append="reduction(item.itemId)"

@click:prepend="increment"
>
<template v-slot:prepend>
<Item
:item="demoItem"
:ratio="0.5"
disable-link
disable-tooltip
/>
</template>
</v-text-field>
</v-flex>
@click:prepend-inner="increment(item.itemId)"

@update:error="status => error = status"
>
<template v-slot:prepend>
<Item
:item="item"
:ratio="0.75"
disable-link
style="margin-top: -7.5px"
/>
</template>
</v-text-field>
</template>

<script>
import get from '@/utils/getters'
import Item from '@/components/Item'
export default {
name: "ItemStepper",
components: {
Expand All @@ -57,63 +67,109 @@
type: Object,
required: true
},
min: {
type: Number,
required: true,
validator: value => {
return value >= 0
}
stage: {
type: String,
required: true
},
max: {
type: Number,
required: true,
validator: value => {
return value >= 0
}
bus: {
type: Object,
required: true
}
},
data () {
return {
value: 0,
rules: {
required: value => !!value || 'Required.',
number: value => isNaN(value) || ''
rawQuantity: 0,
disable: {
actual: false, // the actual disable state of the component
should: false // indicates the types have already been fulfilled, but the component should not been disabled due to errors in the input
},
demoItem: {
"itemId": "2001",
"name": "基础作战记录",
"sortId": 15,
"rarity": 1,
"itemType": "CARD_EXP",
"addTimePoint": 1,
"spriteCoord": [
0,
0
],
"meta": {
"name": "基础作战记录",
"color": "green",
"icon": "mdi-plus"
error: false
}
},
computed: {
quantity: {
get () {
return this.rawQuantity
},
set (v) {
this.rawQuantity = parseInt(v)
}
},
limitations () {
return get.limitations.byStageId(this.stage);
},
validationRules () {
let limitation = this.limitations.itemQuantityBounds.find(v => v.itemId === this.item.itemId);
const gte = (value) => {
return (compare) => {
return compare >= value ? true : this.$t('rules.gte', {item: this.item.name, quantity: value})
}
};
const lte = (value) => {
return (compare) => {
return compare <= value ? true : this.$t('rules.lte', {item: this.item.name, quantity: value})
}
};
const notIncludes = (values) => {
return (compare) => {
return values.indexOf(compare) === -1 ? true : this.$t('rules.not', {item: this.item.name, quantity: values.join(", ")})
}
};
const isNatural = (compare) => {
return ((compare >= 0.0) && (Math.floor(compare) === compare) && compare !== Infinity && !isNaN(compare)) ? true : this.$t('rules.natural');
};
return [
gte(limitation.bounds.lower),
lte(limitation.bounds.upper),
notIncludes(limitation.bounds.exceptions),
isNatural
]
},
valid () {
for (let rule of this.validationRules) {
if (rule(this.quantity) !== true) return false
}
return true
}
},
watch: {
quantity: function (value) {
if (!this.valid) return;
this.$emit("change", [this.item.itemId, value])
},
valid: function (value) {
// the component should be disabled and it's now ready to do it
if (this.valid && this.quantity === 0 && this.disable.should && !this.disable.actual) this.disable.actual = true;
this.$emit("change:valid", value)
}
},
mounted () {
this.bus.$on("fulfilled", this.changeDisable)
},
methods: {
increment () {
if (this.value + 1 <= this.max) {
this.value += 1
}
this.quantity = parseInt(this.quantity) + 1
},
reduction () {
if (this.value - 1 >= this.min) {
this.value -= 1
this.quantity = parseInt(this.quantity);
this.quantity > 0 && (this.quantity -= 1);
this.quantity <= 0 && (this.quantity = 0)
},
changeDisable (fulfilled) {
if (fulfilled) {
this.disable.should = true;
if (this.quantity === 0 && this.valid) {
this.disable.actual = true
}
} else {
this.disable.should = false;
this.disable.actual = false
}
}
},
}
}
</script>

<style scoped>
.itemStepper {
}
</style>
8 changes: 8 additions & 0 deletions src/config/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export default {
api: {
submitParams: {
source: "frontend-v2--development",
version: "v0.0.1"
}
}
}
4 changes: 4 additions & 0 deletions src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,9 @@
"description": "You are currently browsing the development build",
"ok": "OH YEAH!"
}
},
"boolean": {
"true": "Yes",
"false": "No"
}
}
4 changes: 4 additions & 0 deletions src/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,9 @@
"description": "现浏览网页属自动构建的开发用预览版本",
"ok": "OH YEAH!"
}
},
"boolean": {
"true": "",
"false": ""
}
}
12 changes: 0 additions & 12 deletions src/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ export default new Vuex.Store({
})
],
state: {
ajaxLoading: false,
data: {},
settings: {
dark: true,
Expand All @@ -22,22 +21,11 @@ export default new Vuex.Store({
store: (state, d) => {
state.data = {...d}
},
changeAjaxState (state, newState) {
state.ajaxLoading = newState
},
switchDark (state, newState) {
state.settings.dark = newState
},
changeLocale (state, newLocale) {
state.settings.locale = newLocale
}
},
actions: {
ajax_began ({commit}) {
commit('changeAjaxState', true)
},
ajax_finished ({commit}) {
commit('changeAjaxState', false)
}
}
})
13 changes: 0 additions & 13 deletions src/utils/service.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,11 @@
import axios from 'axios'
import store from '@/store'

const service = axios.create({
baseURL: "https://penguin-stats.io/PenguinStats/api"
});

service.interceptors.request.use(function (config) {
store.dispatch("ajax_began")

// Do something before request is sent
return config;
}, function (error) {
// Do something with request error
return Promise.reject(error);
});

// Add a response interceptor
service.interceptors.response.use(function (response) {
store.dispatch("ajax_finished")

// Do something with response data
return response;
}, function (error) {
Expand Down
Loading

0 comments on commit 646e197

Please sign in to comment.