| Server IP : 34.87.99.72 / Your IP : 216.73.217.31 Web Server : Apache/2.4.46 (Unix) OpenSSL/1.1.1n System : Linux zlock-bitnami-lamp-prod-v2-vm 4.19.0-16-cloud-amd64 #1 SMP Debian 4.19.181-1 (2021-03-19) x86_64 User : bitnami ( 1000) PHP Version : 7.4.18 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /opt/bitnami/apache/htdocs/app/resources/js/views/Feedbacks/ |
Upload File : |
<template>
<v-container>
<!-- introduction -->
<v-row align="end">
<v-col>
<div class="headline font-weight-bold">Feedback</div>
<div class="subtitle-2 grey--text">Feedback issued from users.</div>
</v-col>
</v-row>
<v-row dense align="center" justify="end">
<v-spacer></v-spacer>
<v-col cols="auto">
<div class="v-btn-toggle" :class="$vuetify.theme.dark ? 'theme--dark' : 'theme--light' ">
<v-btn
text small
:disabled="model_loading_"
@click="searchData_()"
>
<v-icon small>mdi-refresh</v-icon>
</v-btn>
<v-btn
text small
@click="filter_dialog = true"
>
<v-icon small>mdi-filter-outline</v-icon>
</v-btn>
<v-btn
text small
@click="sort_dialog = true"
>
<v-icon small>mdi-sort</v-icon>
</v-btn>
</div>
</v-col>
</v-row>
<v-card class="mt-4" color="transparent" flat>
<v-data-table
ref="dataTable"
:headers="table_headers"
:items="resourceDataSet_"
:options.sync="settings_"
:server-items-length="totalData_"
:footer-props="{
'items-per-page-options': [5, 10, 25, 50]
}"
:loading="model_loading_"
disable-sort
:item-class="row_classes_"
>
<template #[`item.name`]="{ item }">
<v-row dense class="flex-nowrap ma-0">
<v-col cols="auto">
<v-icon size="40">mdi-account-circle</v-icon>
</v-col>
<v-col class="overflow-hidden">
<div class="primary--text no-word-wrap" :title="item.full_name">{{ item.full_name }}<sup>#{{ item.id }}</sup></div>
<div class="caption grey--text">{{ item.email }}</div>
</v-col>
</v-row>
</template>
<template #[`item.content`]="{ item }">
<div class="no-word-wrap" style="max-width: 100px;">{{ item.content }}</div>
</template>
<template #[`item.created_at`]="{ item }">
{{ $dayjs(item.created_at).format('YYYY-MM-DD hh:mma') }}
</template>
<template #[`item.action`]="{ item }">
<v-icon small @click="viewMore_(item)">mdi-eye</v-icon>
</template>
</v-data-table>
</v-card>
<!-- filter dialog -->
<w-side-dialog
v-model="filter_dialog"
title="Filters"
clearable
@clear="initFilters()"
>
<template #default>
<v-row dense>
<template v-for="(filter,i) in filter_options">
<v-col :key="i" cols="12">
<v-select
v-model="filters_[filter.model]"
:label="filter.label"
:items="filter.items"
class="caption"
outlined
dense hide-details
></v-select>
</v-col>
</template>
</v-row>
</template>
<template #actions>
<div class="text-right">
<v-btn
rounded block color="primary"
@click="searchData_()"
>
Apply
</v-btn>
</div>
</template>
</w-side-dialog>
<!-- Sort dialog -->
<w-side-dialog
v-model="sort_dialog"
title="Sort"
>
<template #default>
<v-radio-group
v-model="sort_"
dense hide-details
mandatory
class="mt-0"
>
<template v-for="(sort,i) in sort_options">
<v-radio :key="i" :label="sort.label" :value="sort.value"></v-radio>
</template>
</v-radio-group>
</template>
<template #actions>
<div class="text-right">
<v-btn
rounded block color="primary"
@click="searchData_()"
>
Apply
</v-btn>
</div>
</template>
</w-side-dialog>
<!-- model info dialog -->
<v-navigation-drawer
v-model="view_dialog_"
floating
app
right
temporary
:style="$vuetify.breakpoint.mdAndUp ? 'min-width: 350px;' : '' "
>
<v-card v-if="Object.keys(view_item_).length > 0" height="100%" class="pa-4">
<v-row dense class="body-1">
<v-col cols="12">
<div class="title primary--text font-weight-bold">{{ view_item_.type }}</div>
<v-divider></v-divider>
</v-col>
<v-col cols="12">
<span>Report by</span>: {{ view_item_.user.full_name }}
</v-col>
<v-col cols="12">
<span>Report time</span>: {{ $dayjs(view_item_.created_at).format('YYYY-MM-DD hh:mma') }}
</v-col>
<v-col cols="12">
<div>Content:</div>
<div
class="display-paragraph px-4 py-2 overflow-auto radius-05"
style="max-height: 60vh; border: 1px solid #AAA; border-left-width: 5px;"
>
<div>{{ view_item_.content }}</div>
</div>
</v-col>
</v-row>
</v-card>
</v-navigation-drawer>
</v-container>
</template>
<script>
import WSideDialog from "@components/WSideDialog"
import { resourceMixin } from "@/js/mixins/ResourceMixin"
import { formActionMixin } from "@/js/mixins/FormActionMixin"
import { errorHandlerMixin } from "@/js/mixins/ErrorHandlerMixin"
export default{
components:{
WSideDialog,
},
mixins: [
resourceMixin,
formActionMixin,
errorHandlerMixin
],
data(){
return {
table_headers: [
{ text: '#', value: 'id' },
{ text: 'Type', value: 'type' },
{ text: 'Report by', value: 'user.full_name' },
{ text: 'Content', value: 'content' },
{ text: 'Report time', value: 'created_at' },
{ text: 'Actions', value: 'action', class: 'text-center' },
],
show_statistics: false,
view_module: false,
filter_dialog: false,
sort_dialog: false,
filter_options:[],
sort_options:[],
}
},
created(){
this.options_.feedback_types = this.getFeedbackType()
this.setupFilterOptions()
this.getAllRefs_([
// this.getUserTypeRefs()
]).then(()=>{
// this.setupFilterBar()
this.initFilters()
this.setupSortOptions()
}).then(()=>{
this.initialize_()
})
},
methods:{
getResourceData_(){
let payload = {
...this.setPagination_(),
...this.search_,
...this.filters_,
...this.sort_,
}
this.model_loading_ = true
this.$api.getFeedback(payload).then((res)=>{
let { data, total } = res.data.result
this.resourceDataSet_ = data
this.totalData_ = total
}).catch((err)=>{
this.errorHandler_(err)
}).finally(()=>{
this.model_loading_ = false
})
},
initFilters(){
this.filters_ = {
type_id : null,
}
},
setupFilterOptions(){
this.filter_options = [
{
cols: 12,
model: "type_id",
label: "Type",
items: [ { value: null, text: "All" }, ...this.options_.feedback_types || [] ],
},
]
},
setupSortOptions(){
this.sort_options = [
{ label: "Reported Time (ASC)", value: {sortBy: "created_at", sortDesc : 0 } },
{ label: "Reported Time (DESC)", value: {sortBy: "created_at", sortDesc : 1 } }
]
},
getFeedbackType(){
return [
{ 'value': 1, 'text': 'Other Matters', },
{ 'value': 2, 'text': 'App Technical Issue', },
{ 'value': 3, 'text': 'Payment Matters', },
]
},
viewMore(item){
console.log(item)
}
}
}
</script>