```=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>
```