Veja nesse artigo
Introdução
Neste artigo vou mostrar como criar a data de vencimento para as tarefas.
Este é uma continuação do Projeto ToDo List com VueJS, caso você queira pegar o código fonte atual do projeto, clique aqui. Ou se preferir ver a playlist com o desenvolvimento do projeto, clique aqui.
Em um sistema de tarefas, uma funcionalidade comum é ter a data de vencimento de uma tarefa, para que o usuário consiga ver que precisa fazer alguma atividade que tem prazo.
Será preciso atualizar o formulário, para colocar o campo da data de vencimento, e também na listagem, para indicar que a tarefa irá vencer.
Preview
A forma que escolhi para mostrar a data foi colocar ao lado direito do título, colado com a borda direita.

Campo de data de vencimento no formulário
A primeira implementação a ser feita, é adicionar o campo que indicará a data de vencimento no formulário de cadastro na tarefa.
Para isso, vou utilizar o campo b-form-datepicker do BootstrapVue, ele é um campo de data já pronto para ser utilizado.
Ao clicar nesse campo, ele abre um mini calendário para que o usuário consiga selecionar a data, facilitando a usabilidade.
<!-- Form.vue -->
<b-form-group label="Data de vencimento" label-for="dateOverdue">
<b-form-datepicker
id="dateOverdue"
v-model="form.dateOverdue"
label-no-date-selected="Selecione uma data"
></b-form-datepicker>
</b-form-group>
A prop label-no-date-selected
é utilizada para definir o texto que vai aparecer, enquanto ainda não há uma data escolhida.
É preciso adicionar a variável dateOverdue
dentro do data do componente, na chave form, para que esse valor seja salvo junto com a tarefa:
//Form.vue
form: {
subject: "",
description: "",
status: Status.OPEN,
dateOverdue: ""
},
Com isso, caso o usuário faça a inclusão de uma tarefa, a data de vencimento dela já irá salvar no “banco” API Rest Fake.
Mostrar a data de vencimento
Com o valor salvo no banco, a próxima etapa é mostrar ele na tela.
Vou adaptar o card, porque atualmente, o titulo está sendo inserido com a prop title, porém como quero mostrar na parte direita do card na frente do título, vou renderizar ele de outra forma.
Vou colocar o código para mostrar o título diretamente no HTML, e depois dele vou colocar a data, para que um fique de um lado do card e o outro no outro, vou utilizar o flexbox para separar.
Vou colocar os dois em uma div, e utilizar o justify-content-between
, isso vai fazer com que cada um fique de um lado, dessa forma:
<!-- List.vue -->
<b-card
class="mb-2"
:class="{ 'finished-task': isFinished(task) }"
>
<div class="d-flex justify-content-between">
<b-card-title>
<span>{{task.subject}}</span>
</b-card-title>
<span>
<b-badge
variant="light">
{{task.dateOverdue}}
</b-badge>
</span>
</div>
<b-card-text>{{ task.description }}</b-card-text>
<!-- ... botões ... -->
</b-card>
Agora, o título vai ficar do lado esquerdo, e a data de vencimento irá ficar do lado direito.
Porém, a data que foi salva no banco, é uma data no formato americano, seria interessante formatar essa data para mostrar na tela.
Para essa formatação, vou utilizar um método, passando a data no formato americano como padrão, e o retorno desse método vai ser a data em formato brasileiro, e vou imprimir na tela o retorno dessa função.
No HTML vai ficar assim:
<!-- List.vue -->
<span>
<b-badge
variant="light">
{{overduePresenter(task.dateOverdue)}}
</b-badge>
</span>
Agora, na parte do Javascript do componente, na chave methods
, vou criar o método overduePresenter
.
//List.vue
overduePresenter(dateOverdue) {
if(!dateOverdue) {
return;
}
return dateOverdue.split('-').reverse().join('/');
},
Este método converte uma data do formato YYYY-MM-DD, para DD/MM/YYYY.
E com isso na tela terá a data formatada no padrão brasileiro, e quando não tiver nenhuma data de vencimento atribuída, o valor fica vazio.
Identificar tarefa vencida
É uma boa, trocar a cor da data quando ela estiver vencida, isso para facilitar para o usuário, de olhar e saber que está vencida.
Para isso, defini algumas cores para utilizar, caso a tarefa esteja vencida, ficará vermelho, caso a tarefa vença hoje, ficará amarelo, caso a tarefa já esteja concluída fica verde, e se não tiver em nenhum desses casos, fica sem cor.
Essa cor será atribuída na prop variant
, ela pode receber todas as cores padrão do BootstrapVue.
Da mesma forma que a exibição da data de vencimento, vou criar um método que irá retornar a cor correta, vou trocar a prop variant para chamar o método:
<!-- List.vue -->
<span>
<b-badge
:variant="variantOverdue(task.dateOverdue, task.status)">
{{overduePresenter(task.dateOverdue)}}
</b-badge>
</span>
E agora vou criar o método variantOverdue
, abaixo do overduePresenter
, que retornará a cor correta para cada estado da tarefa.
//List.vue
variantOverdue(dateOverdue, taskStatus) {
if(!dateOverdue) { //se não tem data, retorna a cor padrão
return 'light';
}
//se a tarefa está concluída, cor verde
if(taskStatus === this.status.FINISHED){
return 'success';
}
//se a tarefa vence hoje, cor amarela
let dateNow = new Date().toISOString().split('T')[0];
if(dateOverdue === dateNow) {
return 'warning';
}
//se a tarefa já venceu, cor vermelha
if(dateOverdue < dateNow) {
return 'danger';
}
//caso não entre em nenhuma condição, cor padrão
return 'light';
}
Dessa forma, agora a tarefa já vai estar com a identificação da data, e com as cores para identificação mais fácil.
Data mínima
O date-picker, mostra um calendário com as datas disponíveis para o usuário selecionar.
Vou colocar uma regra no sistema, que o usuário não poderá preencher uma data de vencimento que já passou.
Para isso é preciso bloquear o date-picker para que o usuário não consiga clicar em datas antigas.
Para fazer isso com o date-picker do BootstrapVue, é possível passar a prop min, para o b-form-datepicker.
E nessa prop vou passar um método, que a função dele vai ser retornar a data atual. Com isso, o usuário não conseguirá preencher uma data antiga.
<!-- Form.vue -->
<b-form-group label="Data de vencimento" label-for="dateOverdue">
<b-form-datepicker
id="dateOverdue"
v-model="form.dateOverdue"
label-no-date-selected="Selecione uma data"
:min="getToday()"
></b-form-datepicker>
</b-form-group>
E o método getToday fica assim:
//Form.vue
getToday() {
return new Date().toISOString().split('T')[0];
}
Agora o calendário abrirá com a possibilidade somente de selecionar as datas futuras.
Vídeo
Código fonte
O código fonte está no meu CodeSandbox, neste link.
Para ver outros canais onde o posto conteúdo sobre VueJS, veja os Links do Programando Soluções.
Conclusão
Uma função comum para um aplicativo de tarefas, é ter a data para o vencimento de uma tarefa.
Com esse código fiz a implementação da data de maneira fácil e com recursos interessantes, mantendo o padrão da tela e deixando fácil de forma visual para identificar se a tarefa está perto de vencer ou vencida.
Referências
https://bootstrap-vue.org/docs/components/form-datepicker#form-datepicker
https://bootstrap-vue.org/docs/reference/color-variants#color-variants-and-css-class-mapping