? Tela: Criar Novo Evento da Agenda

Rota: /Agenda/Create

Método HTTP: GET (exibir formulário) / POST (salvar evento)

Permissão necessária: Administrador ou Gerente

?? Visão Geral da Tela

Formulário completo para cadastro de eventos da agenda com suporte a tipos padronizados, autocomplete de turmas, validação HTML5 e integração com Choices.js.

?? Elementos da Interface

1. Cabeçalho da Página

  • Breadcrumb: Home ? Agenda ? Adicionar Evento
  • Título: "Novo Evento da Agenda" (ícone ti-calendar-plus)
  • Subtitle: "Cadastre eventos com os tipos padronizados do sistema e conecte a uma turma específica."
  • Botão secundário: "Voltar para Agenda" (outline-secondary, link para /Agenda)

2. Layout do Formulário

Formulário dividido em 2 colunas:

  • Coluna principal (col-lg-8): 3 cards com campos de dados
  • Sidebar (col-lg-4): 2 cards com data/horário e botões de ação

?? Campos do Formulário

Card 1: Informações Principais

Campo Tipo Obrigatório Placeholder
Titulo text Sim (*) "Ex.: Reunião com Comissão"
Descricao textarea (4 rows) Não "Resumo do objetivo, pauta ou detalhes importantes do evento"

Card 2: Tipo e Localização

Campo Tipo Obrigatório Detalhes
Tipo text + datalist Sim (*) Autocomplete com ViewBag.EventTypes (dinâmico)
TipoEvento (hidden) hidden - Sincronizado via JS com campo "Tipo"
Local text Não "Informe o local ou deixe em branco para definir depois"

Card 3: Vinculação e Observações

Campo Tipo Obrigatório Detalhes
TurmaId select (Choices.js) Não ViewBag.Turmas ordenado por nome, com curso. Placeholder: "Evento Geral"
Status select (Choices.js) Não 4 opções: Agendado, Confirmado, Cancelado, Concluído
IsPublico checkbox switch Não Label: "Evento público (visível para todos os usuários da turma)"

Sidebar Card 1: Data e Horário

Campo Tipo Obrigatório Observação
DataEvento date Sim (*) Formato yyyy-MM-dd
HoraEvento time Não Horário principal do evento
HoraInicio time Não Horário de início (col-md-6)
HoraFim time Não Horário de término (col-md-6)

Sidebar Card 2: Botões de Ação

  • Salvar Evento: Botão primário com ícone ti-device-floppy (submit)
  • Cancelar: Botão light (link para /Agenda/Index)

?? Funcionalidades JavaScript

Sincronização de Campos (Tipo ? TipoEvento)

const syncTipo = () => {
    tipoEventoHidden.value = tipoInput.value || "";
};

tipoInput.addEventListener("input", syncTipo);
tipoInput.addEventListener("blur", syncTipo);
form.addEventListener("submit", syncTipo);
        

Choices.js - Autocomplete de Turma

new Choices(turmaSelect, {
    searchEnabled: true,
    searchPlaceholderValue: "Buscar turma...",
    noResultsText: "Nenhuma turma encontrada",
    itemSelectText: "Clique para selecionar",
    shouldSort: false,
    removeItemButton: true,
    placeholder: true,
    placeholderValue: "Selecione uma turma"
});
        

Choices.js - Autocomplete de Status

new Choices(statusSelect, {
    searchEnabled: true,
    searchPlaceholderValue: "Buscar status...",
    noResultsText: "Nenhum status encontrado",
    itemSelectText: "Clique para selecionar",
    shouldSort: false,
    removeItemButton: false,
    placeholder: false
});
        

? Validação do Formulário

Validação HTML5

  • Atributo required em: Titulo, Tipo, DataEvento
  • Atributo novalidate no form para controle custom
  • Classe needs-validation para feedback visual do Bootstrap

Validação Server-Side

  • @Html.ValidationSummary exibe erros gerais
  • asp-validation-for em cada campo exibe erros específicos
  • TempData para mensagens de sucesso/erro após POST

?? Notificações e Feedback

Sucesso

Alert verde dismissível após criação: "Evento criado com sucesso!" (via TempData)

Erro

Alert vermelho dismissível com descrição do erro (via TempData ou ValidationSummary)

?? Regras de Negócio

  • Título, Tipo e Data são obrigatórios
  • TurmaId null/empty = Evento Geral (não vinculado a turma)
  • Status padrão: "agendado"
  • IsPublico padrão: false (não marcado)
  • Campo "Tipo" permite digitação livre (não apenas opções do datalist)
  • Campo "TipoEvento" (hidden) é sincronizado para compatibilidade com backend
  • Horários são opcionais (evento pode ter apenas data)
  • HoraInicio/HoraFim são independentes de HoraEvento (uso depende da lógica de negócio)

?? Integração com API

GET /Agenda/Create

  • Retorna view com Model vazio (Evento)
  • ViewBag.Turmas: IEnumerable<Turma>
  • ViewBag.EventTypes: IEnumerable<string>

POST /Agenda/Create

  • Content-Type: application/x-www-form-urlencoded
  • Antiforgery token obrigatório
  • Model binding automático para Evento
  • Redirect após sucesso: /Agenda/Index (com TempData)
  • Retorno em caso de erro: Mesma view com ModelState

?? Navegação

  • Ao salvar com sucesso: Redireciona para /Agenda/Index
  • Ao clicar em "Cancelar": Redireciona para /Agenda/Index
  • Ao clicar em "Voltar para Agenda": Redireciona para /Agenda/Index
  • Breadcrumb Home: /Dashboard/Index
  • Breadcrumb Agenda: /Agenda/Index

?? Responsividade

  • Layout 2 colunas em desktop (8/4), empilha em mobile
  • Campos Início/Fim lado a lado em tablet+, empilhados em mobile
  • Choices.js é responsivo por padrão

?? Bibliotecas Externas

  • Choices.js 10.2.0: Autocomplete para selects
  • estudio-autocomplete.js: Script customizado (se existir)
  • Bootstrap 5: Grid, forms, validação
  • Tabler Icons: Ícones de interface