```=javascript= <template> <v-container fluid> <snack-alert ref="alert" /> <!-- Header --> <div class="d-flex justify-start pl-3"> <span class="dashboard-title raleway"> Cadastro de empresa </span> </div> <v-divider color="black" /> <v-row class="d-flex flex-column-reverse flex-sm-row justify-space-between align-center" > <v-col cols="12" sm="12" md="6" lg="6"> <v-btn color="success" dark @click="openCreate()">adicionar</v-btn> </v-col> <v-col cols="12" sm="12" md="6" lg="6" class="d-flex justify-end"> <div class="dashboard-search"> <v-text-field v-model="search" append-icon="mdi-magnify" label="pesquisar" single-line flat hide-details /> </div> </v-col> </v-row> <!-- Header --> <!-- Table --> <v-data-table class="elevation-3" :search="search" :items="registrationEnterprise" :headers="headers" calculate-windths > <template v-slot:[`item.action`]="{ item }"> <v-icon mediom class="mr-2" color="primary" @click="openEdit(item)" >mdi-circle-edit-outline</v-icon > <v-icon mediom color="error" @click="deleteEnterprise(item)" >mdi-delete</v-icon > </template> </v-data-table> <template v-slot:[`item.validTo`]="{ item }"> <span> {{ formatDate(item) }} </span> </template> <!-- Table --> <!-- Dialog criação/edição --> <v-dialog v-model="isDialogOpen" max-width="800px" no-click-animation persistent > <v-card> <v-card-title class="headline"> {{ dialogTitle }} </v-card-title> <v-card-text> <v-form ref="form"> <v-text-field v-model="editedItem.cnpj" label="CNPJ" item-value="cnpj" :rules="[(v) => !!v || 'Campo obrigatório']" :value="formatCNPJ(editedItem.cnpj)" /> <v-text-field v-model="editedItem.reason" label="Razão social" item-value="reason" :rules="[(v) => !!v || 'Campo obrigatório']" /> <v-text-field v-model="editedItem.name" label="Nome fantasia" item-value="name" :rules="[(v) => !!v || 'Campo obrigatório']" /> <v-text-field v-model="editedItem.email" label="E-mail" item-value="email" :rules="[ (v) => !!v || 'Campo obrigatório', (v) => /.+@.+\..+/.test(v) || 'E-mail must be valid', ]" /> <!-- Form data --> <v-row> <v-col cols="12" sm="6" md="4"> <v-dialog ref="dialog" v-model="modal" :return-value.sync="dates" persistent width="290px" > <template v-slot:activator="{ on, attrs }"> <v-text-field v-model="dateRangeText" label="Período datas" prepend-icon="mdi-calendar" readonly v-bind="attrs" v-on="on" ></v-text-field> </template> <v-col cols="12"> <v-date-picker v-model="dates" range> </v-date-picker> </v-col> <v-spacer></v-spacer> <v-btn text color="primary" @click="modal = false"> Cancel </v-btn> <v-btn text color="primary" @click="$refs.dialog.save(dates)"> OK </v-btn> </v-dialog> </v-col> </v-row> <!-- Form data --> </v-form> </v-card-text> <v-card-actions> <v-spacer /> <v-btn color="black" text @click="closeDialog()">Cancelar</v-btn> <v-btn color="success" @click="onSubmit()">Salvar</v-btn> </v-card-actions> </v-card> </v-dialog> <!-- Dialog criação/edição --> </v-container> </template> <script> import SnackAlert from '~/components/globals/SnackAlert.vue' export default { layout: 'dashboard', components: { SnackAlert, }, async asyncData({ $axios }) { const [registrationEnterpriseRes] = await Promise.all([ $axios.get('client'), ]) return { registrationEnterprise: registrationEnterpriseRes.data.data, } }, /* PARA DEBUG watch: { dates(newValue, oldValue) { console.log('Mudou para: ', newValue) console.log('Era: ', oldValue) }, }, */ data() { return { registrationEnterprise: [], date: new Date(Date.now() - new Date().getTimezoneOffset() * 60000) .toISOString() .substr(0, 10), modal: false, dates: [], search: '', dialogTitle: '', isDialogOpen: false, isEdit: false, editedItem: { id: '', cnpj: '', reason: '', name: '', email: '', }, headers: [ { text: 'CNPJ', align: 'left', sortable: true, value: 'cnpj' }, { text: 'Razão social', align: 'left', sortable: true, value: 'reason', }, { text: 'Nome fantasia', align: 'left', sortable: true, value: 'name' }, { text: 'Válido desde', align: 'left', sortable: true, value: 'validFrom', }, { text: 'Válido até', align: 'left', sortable: true, value: 'validTo' }, { text: 'E-mail', align: 'left', sortable: true, value: 'email' }, { text: '', align: 'right', sortable: false, value: 'action' }, ], } }, computed: { dateRangeText() { return this.dates.join(' ~ ') }, }, methods: { formatDate(array) { let formatDate = '' array.forEach((item, i) => { formatDate += item.validTo if (array.length - 1 > 0) { formatDate += ' - ' } }) return formatDate }, openCreate() { this.dialogTitle = 'Adicione uma empresa' this.setState(false, true) }, openEdit(item) { Object.assign(this.editedItem, item) this.dialogTitle = 'Edite dados da empresa' this.setState(true, true) }, closeDialog() { this.setState(false, false) }, setState(edit, dialog) { this.isEdit = edit this.isDialogOpen = dialog }, onSubmit() { if (!this.$refs.form.validate()) return this.isEdit ? this.updateEnterprise() : this.createEnterprise() }, createEnterprise() { const enterprise = new FormData() enterprise.append('cnpj', this.editedItem.cnpj) // console.log(this.editedItem.cnpj) enterprise.append('reason', this.editedItem.reason) enterprise.append('name', this.editedItem.name) enterprise.append('validFrom', this.dates[0]) enterprise.append('validTo', this.dates[1]) enterprise.append('email', this.editedItem.email) /* for (const value of image.values()) { console.log(value) } */ this.$axios .post('client', enterprise) .then(() => { this.$refs.alert.showSnackBar({ color: 'success', text: 'Empresa criada com sucesso!', }) this.$nuxt.refresh() this.setState(false, false) this.editedItem.cnpj = '' this.editedItem.reason = '' this.editedItem.name = '' this.editedItem.email = '' }) .catch(() => { this.$refs.alert.showSnackBar({ color: 'error', text: 'Erro ao criar empresa', }) }) }, formatCNPJ(cnpj) { // Remover caracteres indesejados cnpj = cnpj.replace(/\D/g, '') // Aplicar máscara cnpj = cnpj.replace(/(\d{2})(\d)/, '$1.$2') cnpj = cnpj.replace(/(\d{3})(\d)/, '$1.$2') cnpj = cnpj.replace(/(\d{3})(\d)/, '$1/$2') cnpj = cnpj.replace(/(\d{4})(\d)/, '$1-$2') return cnpj }, updateEnterprise() { this.$axios .put(`client/${this.editedItem.id}`, { cnpj: this.editedItem.cnpj, reason: this.editedItem.reason, name: this.editedItem.name, validFrom: this.dates[0], validTo: this.dates[1], email: this.editedItem.email, }) .then(() => { this.$refs.alert.showSnackBar({ color: 'success', text: 'Atualização de dados bem sucedido', }) this.$nuxt.refresh() this.setState(false, false) }) .catch(() => { this.$refs.alert.showSnackBar({ color: 'error', text: 'Erro ao atualizar dados', }) }) }, deleteEnterprise(item) { const ok = window.confirm('Você deseja deletar esse item') if (ok) { this.$axios .delete(`client/${item.id}`) .then(() => { this.$refs.alert.showSnackBar({ color: 'success', text: 'Item deletado com sucesso!', }) this.$nuxt.refresh() // Refresh nas informações this.setState(false, false) // Close Dialog }) .catch(() => { this.$refs.alert.showSnackBar({ color: 'error', text: 'Erro ao deletar item', }) }) } }, }, } </script> <style scoped> .dashboard-title { font-size: 45px; font-weight: bold; } .dashboard-search { max-width: 500px; width: 100%; } .dashboard-edit-icon { position: absolute; right: 3px; top: 3px; } </style> ```