better customer list/dashboard

This commit is contained in:
Paul Wilde 2023-03-21 16:57:39 +00:00
parent a46eebe5d3
commit 9f073ddba3
4 changed files with 208 additions and 87 deletions

View file

@ -5,7 +5,7 @@
<v-textarea v-model="comment" label="Comment"></v-textarea> <v-textarea v-model="comment" label="Comment"></v-textarea>
</v-card-text> </v-card-text>
<v-card-actions> <v-card-actions>
<v-btn color="blue" @click="saveComment">Save</v-btn> <v-btn color="blue" :loading="saving" @click="saveComment">Save</v-btn>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-btn color="grey" @click="$emit('return','cancel')">Cancel</v-btn> <v-btn color="grey" @click="$emit('return','cancel')">Cancel</v-btn>
</v-card-actions> </v-card-actions>

View file

@ -0,0 +1,98 @@
<template>
<h3>Comments <v-btn v-if="customer != null" color="warning" size="smaller" variant="text" icon="mdi-plus" @click="showAddNote"></v-btn></h3>
<v-progress-linear color="yellow" :active="comments_loading" indeterminate>
</v-progress-linear>
<v-list>
<v-list-item v-for="item in comments" :key="item.id">
{{ item.comment }}
<template v-slot:append>
<v-icon v-if="item.actioned" icon="mdi-tick" color="green" title="Actioned"></v-icon>
<v-btn v-if="item.active" :loading="item.active_changing" @click="toggleActiveState(item)" size="small" icon="mdi-play" color="blue" title="Active"></v-btn>
<v-btn v-if="!item.active" :loading="item.active_changing" @click="toggleActiveState(item)" size="small" icon="mdi-pause" title="Inactive"></v-btn>
</template>
</v-list-item>
</v-list>
<v-dialog v-model="dialog[0]">
<AddNote :customer="customer" @return="closeAddNote"></AddNote>
</v-dialog>
</template>
<script>
import Customer from '@/types/CustomerType.vue'
import AddNote from '@/components/AddNote.vue'
import axios from 'axios'
export default {
props: {
customer: new Customer()
},
components: {
AddNote
},
data(){
return {
comments_loading: null,
comments: [],
active_changing: false,
dialog: {}
}
},
watch: {
customer() {
this.getCustomerComments(this.customer.acc_no)
}
},
methods: {
showAddNote() {
this.dialog[0] = true
},
closeAddNote(e){
if (e == "saved"){
this.getCustomerComments()
}
this.dialog[0] = false
},
getCustomerComments(){
this.comments_loading = true
let url = this.$api_url + "/customers/comments"
axios.get(url,{
params: {
acc_no: this.customer.acc_no
}
})
.then(resp => {
this.comments = resp.data
})
.catch(error => (console.log(error)))
.finally(() => {
this.comments_loading = false
})
},
toggleActiveState(cmt){
cmt.active_changing = true
let url = this.$api_url + "/customers/comments/" + cmt.id + "/active"
axios.put(url,{
state: !cmt.active
})
.then(resp => {
console.log(resp.data)
this.getActiveState(cmt)
})
.catch(err => {
console.log(err)
})
},
getActiveState(cmt) {
let url = this.$api_url + "/customers/comments/" + cmt.id + "/active"
axios.get(url)
.then(resp => {
cmt.active = resp.data
})
.catch(err => {
console.log(err)
})
.finally(() => {
cmt.active_changing = false
})
},
}
}
</script>

View file

@ -0,0 +1,80 @@
<template>
<h3>Recent Orders - {{ customer.acc_no }} {{ customer.name }}</h3>
<v-progress-linear color="blue" :active="orders_loading" indeterminate>
</v-progress-linear>
<v-container>
<v-row>
<v-col cols=4 v-for="item in sortedOrders" :key="item.id">
<v-card>
<v-card-title>
Order: {{ item.doc_no }}
</v-card-title>
<v-card-subtitle>
{{ formatDate(item.doc_date,"DD/MM/YYYY") }}
</v-card-subtitle>
<v-card-text>
<v-list>
<v-list-item v-for="(i, index) in item.products" :key="index" style="border-bottom: 1px dotted #000;">
{{ i.code }} - {{ i.name }} x {{ i.quantity }}
</v-list-item>
</v-list>
</v-card-text>
</v-card>
</v-col>
</v-row>
</v-container>
</template>
<script>
import axios from 'axios'
import Customer from '@/types/CustomerType.vue'
import methods from '@/CommonMethods.vue'
export default {
props:{
customer: new Customer()
},
watch: {
customer() {
this.getCustomerRecentOrders(this.customer.acc_no)
}
},
mixins: [methods],
data() {
return {
orders_loading: false,
orders: []
}
},
computed: {
sortedOrders() {
let sorted = this.orders
sorted.sort((a, b) => {
if (a.doc_date < b.doc_date){
return 1
}
if (a.doc_date > b.doc_date){
return -1
}
return 0
})
return sorted
}
},
methods: {
getCustomerRecentOrders(acc_no){
this.orders_loading = true
let url = this.$api_url + "/customers/" + acc_no + "/orders/recent"
axios.get(url)
.then(resp => {
this.orders = resp.data
})
.catch(err => {
console.log(err)
})
.finally(() => {
this.orders_loading = false
})
}
}
}
</script>

View file

@ -21,7 +21,7 @@
> >
<v-list-item > <v-list-item >
<template v-slot:title > <template v-slot:title >
<v-card @click="getCustomerComments(item)"> <v-card @click="getCustomerInfo(item)">
{{ item.acc_no }} - {{ item.name }}: {{ item.acc_no }} - {{ item.name }}:
<span class="text-caption">{{ item.address.line_1 }}, {{ item.address.line_2 }}, <br/> <span class="text-caption">{{ item.address.line_1 }}, {{ item.address.line_2 }}, <br/>
{{ item.address.city }}, {{ item.address.county}}, {{ item.address.postcode }}, {{ item.address.city }}, {{ item.address.county}}, {{ item.address.postcode }},
@ -29,36 +29,32 @@
</v-card> </v-card>
</template> </template>
<template v-slot:append> <template v-slot:append>
<v-btn @click.prevent="goToContracts(item)" color="info">Contracts</v-btn> <v-btn @click.prevent="goToContracts(item)" color="info">
<v-btn @click.prevent="goToMedFeeds(item)" color="warning">Med Feeds</v-btn> Contracts
<v-badge v-if="item.contract_count > 0" :content="item.contract_count">
</v-badge>
</v-btn>
<v-btn @click.prevent="goToMedFeeds(item)" color="warning">
Med Feeds
<v-badge v-if="item.medfeed_count > 0" :content="item.medfeed_count">
</v-badge>
</v-btn>
</template> </template>
</v-list-item> </v-list-item>
</RecycleScroller> </RecycleScroller>
</v-list> </v-list>
<CustomerComments :customer="selected_cust"></CustomerComments>
</v-col> </v-col>
<v-col cols="12" sm=12 lg=6> <v-col cols="12" sm=12 lg=6>
<h3>Comments <v-btn v-if="selected_cust != null" color="warning" size="smaller" variant="text" icon="mdi-plus" @click="showAddNote"></v-btn></h3> <RecentOrders :customer="selected_cust"></RecentOrders>
<v-progress-linear color="blue" :active="comments_loading" indeterminate>
</v-progress-linear>
<v-list>
<v-list-item v-for="item in comments" :key="item.id">
{{ item.comment }}
<template v-slot:append>
<v-icon v-if="item.actioned" icon="mdi-tick" color="green" title="Actioned"></v-icon>
<v-btn v-if="item.active" :loading="item.active_changing" @click="toggleActiveState(item)" size="small" icon="mdi-play" color="blue" title="Active"></v-btn>
<v-btn v-if="!item.active" :loading="item.active_changing" @click="toggleActiveState(item)" size="small" icon="mdi-pause" title="Inactive"></v-btn>
</template>
</v-list-item>
</v-list>
</v-col> </v-col>
</v-row> </v-row>
<v-dialog v-model="dialog[0]">
<AddNote :customer="selected_cust" @return="closeAddNote"></AddNote>
</v-dialog>
</template> </template>
<script> <script>
import axios from 'axios'; import axios from 'axios';
import AddNote from '@/components/AddNote.vue' import RecentOrders from '@/components/RecentOrders.vue'
import CustomerComments from '@/components/CustomerComments.vue'
import Customer from '@/types/CustomerType.vue'
export default { export default {
props: { props: {
site_info: {}, site_info: {},
@ -69,17 +65,14 @@ export default {
searchQuery: "", searchQuery: "",
customer_list: [], customer_list: [],
customers_loading: null, customers_loading: null,
selected_cust: null, selected_cust: new Customer(),
limit: 5000, limit: 5000,
listreceived: false, listreceived: false,
comments_loading: null,
comments: [],
active_changing: false,
dialog: {}
} }
}, },
components: { components: {
AddNote RecentOrders,
CustomerComments
}, },
computed: { computed: {
filteredCustomers() { filteredCustomers() {
@ -99,65 +92,15 @@ export default {
}, },
}, },
methods: { methods: {
getCustomerInfo(c) {
this.selected_cust = c
},
goToContracts(c){ goToContracts(c){
this.$router.push('/customers/contracts/list/' + c.acc_no) this.$router.push('/customers/contracts/list/' + c.acc_no)
}, },
goToMedFeeds(c){ goToMedFeeds(c){
this.$router.push('/customers/medicated-feeds/list/' + c.acc_no) this.$router.push('/customers/medicated-feeds/list/' + c.acc_no)
}, },
showAddNote() {
this.dialog[0] = true
},
closeAddNote(e){
this.dialog[0] = false
if (e == "saved"){
this.getCustomerComments(this.selected_cust)
}
},
getCustomerComments(cust){
this.selected_cust = cust
this.comments_loading = true
let url = this.$api_url + "/customers/comments"
axios.get(url,{
params: {
acc_no: cust.acc_no
}
})
.then(resp => {
this.comments = resp.data
})
.catch(error => (console.log(error)))
.finally(() => {
this.comments_loading = false
})
},
toggleActiveState(cmt){
cmt.active_changing = true
let url = this.$api_url + "/customers/comments/" + cmt.id + "/active"
axios.put(url,{
state: !cmt.active
})
.then(resp => {
console.log(resp.data)
this.getActiveState(cmt)
})
.catch(err => {
console.log(err)
})
},
getActiveState(cmt) {
let url = this.$api_url + "/customers/comments/" + cmt.id + "/active"
axios.get(url)
.then(resp => {
cmt.active = resp.data
})
.catch(err => {
console.log(err)
})
.finally(() => {
cmt.active_changing = false
})
},
async getCustomerList() { async getCustomerList() {
this.customers_loading = true this.customers_loading = true
let url = this.$api_url + "/customers/list" let url = this.$api_url + "/customers/list"
@ -178,7 +121,7 @@ export default {
</script> </script>
<style scoped> <style scoped>
.scroller { .scroller {
height: 500px; height: 600px;
} }
.scroller.small { .scroller.small {
height: 200px; height: 200px;