# 04 — Views e UX do Módulo Diário Oficial

---

## 1. Blades do CMS (`v6/resources/views/prefecture/contents/`)

### 1.1 Diário Oficial

| Arquivo | Função |
|---------|--------|
| `diario-oficial/index.blade.php` | Listagem do CMS (DataTable) com botões "Cadastrar", "Certificados", "Configurações" e exclusão em lote |
| `diario-oficial/create.blade.php` | **Wrapper** do formulário: serve tanto para criação quanto para edição; hospeda o polling do PDF e o modal de matérias |
| `diario-oficial/form.blade.php` | Formulário propriamente dito (edição, autor, e-mail, data de publicação, certificado, colunas, lei validadora, capa, workflow) |
| `diario-oficial/loading.blade.php` | Tela de carregamento exibida dentro do iframe de preview |
| `diario-oficial/modal/areas/modal.blade.php` | Modal de gerenciamento de matérias (Summernote + upload de PDF) |
| `diario-oficial/modal/areas/index.blade.php` | Listagem das matérias dentro do modal |
| `diario-oficial/components/pdf-file-upload.blade.php` | Componente de upload de PDF da matéria |
| `diario-oficial/components/image.blade.php` | Componente de imagem genérico |
| `diario-oficial/components/cover-image.blade.php` | Upload, preview e remoção da imagem de capa |

### 1.2 Áreas e subáreas

| Arquivo | Função |
|---------|--------|
| `diario-oficial/diario-areas/index.blade.php` | Listagem de áreas |
| `diario-oficial/diario-areas/create.blade.php` | Wrapper do formulário de área |
| `diario-oficial/diario-areas/form.blade.php` | Formulário de área |
| `diario-oficial/diario-subareas/index.blade.php` | Listagem de subáreas |
| `diario-oficial/diario-subareas/create.blade.php` | Wrapper do formulário de subárea |
| `diario-oficial/diario-subareas/form.blade.php` | Formulário de subárea |

### 1.3 Configurações

| Arquivo | Função |
|---------|--------|
| `diario-oficial/configuracoes/create.blade.php` | Tela de configurações globais |
| `diario-oficial/configuracoes/form.blade.php` | Formulário: lei padrão, certificado padrão, status padrão, posição do logo, imagem de cabeçalho |

### 1.4 Templates legados de PDF (órfãos)

| Arquivo | Função |
|---------|--------|
| `diario-oficial/pdf/index.blade.php` | Template HTML legado; o PDF real vem do `FPdfService`, não deste arquivo |
| `diario-oficial/pdf/style.blade.php` | CSS do template legado |
| `diario-oficial/pdf/summernote.blade.php` | **Não é o Summernote**: é um bundle de CSS (normalize + Bootstrap 3 + Glyphicons) com ~7.300 linhas |

### 1.5 Preview do PDF

| Arquivo | Função |
|---------|--------|
| `prefecture/contents/components/preview/diario-oficial/index.blade.php` | Shell do iframe de preview do PDF |
| `prefecture/contents/components/preview/diario-oficial/style.blade.php` | Cópia órfã do CSS de `pdf/style.blade.php` |
| `prefecture/contents/components/preview/diario-oficial/summernote.blade.php` | Cópia órfã do bundle CSS de `pdf/summernote.blade.php` |

### 1.6 Certificados

| Arquivo | Função |
|---------|--------|
| `prefecture/contents/certificado/index.blade.php` | Listagem de certificados digitais |
| `prefecture/contents/certificado/create.blade.php` | Wrapper do formulário de certificado |
| `prefecture/contents/certificado/form.blade.php` | Upload do `.pfx`/`.p12` + senha |

## 2. Blades do portal (`v6/resources/views/portal/layouts/diario-oficial/`)

| Arquivo | URL | Função |
|---------|-----|--------|
| `index.blade.php` | `/diario-oficial` | Listagem pública com painel de filtros (data início, data final, palavra-chave, edição) e lista de edições |
| `show-pdf.blade.php` | `/diario-oficial/{id}` | Visualizador: `<embed>` do PDF + painel lateral com logo, identificação da edição, tamanho, assinatura digital, busca e navegação entre edições. **HTML autônomo**, não estende o layout do portal |
| `auditoria.blade.php` | `/diario-oficial/{id}/auditoria` | Trilha de auditoria pública (LGPD) |

### Layouts do portal

O portal usa o **template ativo** do site, resolvido por `getTemplateActived()`
(`App\Http\Traits\AppTrait`). As telas do diário ficam em
`portal/layouts/diario-oficial/` e são renderizadas dentro de
`portal.layouts.{model}.layout.layout`, onde `{model}` é o template ativo
(`default`, `modelo1` a `modelo5`). A tela `show-pdf.blade.php` é a exceção:
monta o HTML completo por conta própria para poder exibir o `<embed>` sem o
cabeçalho do portal.

## 3. O que o operador vê (CMS)

### 3.1 Listagem (`diario-oficial/index.blade.php`)

DataTable alimentada por `GET /cms/datatable/diario_oficial` (view
`diario_oficial`). Colunas visíveis:

| Coluna | Origem |
|--------|--------|
| Edição | `value` |
| Autor | `autor` |
| Data de publicação | `data_publicacao` (DD/MM/AAAA) |
| Status | `status` (Ativado / Desativado) + badge de `status_workflow` |
| Ações | Atualizar, Download, Ativar/Inativar, Editar, Excluir |

A coluna de ações é montada pelo JavaScript, respeitando as permissões do
usuário (ver `03-ROTAS-E-CONTROLADORES.md`, seção 7.3).

Badges de **status de geração** são atualizados por polling:
`GET /cms/ajax/diario-generation-status/{id}`.

### 3.2 Formulário (`diario-oficial/create.blade.php` + `form.blade.php`)

Campos:

| Campo | Validação |
|-------|-----------|
| Edição | obrigatório (pré-preenchido com `max(edicao) + 1`) |
| Autor | obrigatório |
| E-mail | obrigatório |
| Data de publicação | obrigatório |
| Lei validadora | opcional (pré-preenchida com `diario_configs.lei_padrao`) |
| Certificado | `SelectRule` |
| Colunas | 1, 2 ou 3 |
| Linha divisória | `has_line` + `line_style` + `line_color` |
| Imagem de capa | `archive_highlight`, imagem, até 5 MB |

Ações disponíveis: salvar, **enviar para revisão**, publicar (visível apenas
para quem pode), "Processar PDF", preview, excluir capa.

### 3.3 Modal de matérias

Abre a partir da tela de edição. Permite:

- criar matéria **textual** (HTML via Summernote) ou **com anexo PDF**;
- escolher área e subárea;
- marcar "incorporar no fluxo" (`file_in`);
- reordenar por drag & drop;
- editar e excluir.

## 4. O que o visitante vê (portal)

### 4.1 Listagem

Painel de filtros à esquerda (data de início, data final, palavra-chave,
edição) e lista de edições à direita, com data e botão "Visualizar". O filtro
é aplicado por JavaScript, com POST para `/diario-oficial/filtro`; o
resultado é renderizado em `<ul id="diarioZona">`.

### 4.2 Visualizador

- `<embed>` com o PDF.
- Painel lateral: logo da instituição, nome da prefeitura, tamanho do
  arquivo (via `file-info`), número da edição, data de publicação, assinatura
  digital (responsável, e-mail, lei validadora).
- Campo de busca: retorna as páginas do PDF onde o termo ocorre, com trechos
  de contexto.
- Botões "Anterior" e "Próxima" navegam entre edições **por número de edição**
  (não por data), o que funciona mesmo com duas edições no mesmo dia.
- Link para a trilha de auditoria da edição.

Quando o PDF ainda não existe, a tela exibe o estado "Gerando PDF" e o
diário fica com `generation_status = 'pending'` — **sem consumidor** (ver
`08-GAPS-E-DIVIDAS.md`).

## 5. JavaScript

### 5.1 CMS

| Arquivo | Função |
|---------|--------|
| `v6/public/assets/js/custom/contents/diario-oficial/index.js` | Toggle de status (`POST /cms/diario/status`) a partir dos botões `.toogle-status` |
| `v6/public/assets/js/custom/contents/diario-oficial/datatable.js` | Configuração da DataTable da listagem (colunas, botões, ordenação) |
| `v6/public/assets/js/custom/contents/diario-oficial/generation-status.js` | Polling de `GET /cms/ajax/diario-generation-status/{id}` para atualizar os badges de geração |
| `v6/public/assets/js/custom/contents/diario-oficial/areas.js` | Modal de matérias: CRUD, upload de PDF, reordenação |
| `v6/public/assets/js/custom/contents/diario-oficial/areas-diario/index.js` | Habilita o botão "Salvar" do formulário de área |
| `v6/public/assets/js/custom/contents/diario-oficial/config.js` | Upload, preview e remoção da imagem de cabeçalho das configurações |
| `v6/public/assets/js/custom/contents/diario-oficial/cover-image.js` | Upload, preview e remoção da imagem de capa |
| `v6/public/assets/js/custom/contents/diario-oficial/diario_portal.js` | Filtros da listagem pública |
| `v6/public/assets/js/custom/contents/areas-do-diario/datatable.js` | DataTable de áreas |
| `v6/public/assets/js/custom/contents/sub-areas-diario/datatable.js` | DataTable de subáreas |
| `v6/public/assets/js/custom/utilities/helpers/preview-diario.js` | Helper do preview no CMS (hoje **órfão**: foi removido do `create.blade.php`) |

### 5.2 Portal

| Arquivo | Função |
|---------|--------|
| `v6/public/assets/js/custom/portal/diario-oficial/viewer.js` | Visualizador: `file-info`, busca de edição, busca dentro do PDF, navegação entre edições |
| `v6/public/assets/js/custom/contents/diario-oficial/diario_portal.js` | Filtros da listagem pública |

### 5.3 CSS

| Arquivo | Função |
|---------|--------|
| `v6/public/assets/css/portal/diario-oficial-viewer.css` | Estilos do visualizador público |

### 5.4 Editor de texto

| Item | Onde |
|------|------|
| `v6/public/assets/js/custom/utilities/richtext/summernote.js` | Wrapper do Summernote realmente carregado |
| `v6/public/assets/plugins/summernote/summernote.min.js` | Plugin Summernote |
| `v5/public/assets/plugins/summernote/summernote-diario.js` | Fork do Summernote **existente apenas no v5**; não está no v6 |

## 6. Endpoints chamados por Ajax

| Chamador | Método | Endpoint | Retorno |
|----------|--------|----------|---------|
| `datatable.js` (CMS) | GET | `/cms/datatable/diario_oficial` | JSON da DataTable |
| `datatable.js` (áreas) | GET | `/cms/datatable/areas_diario` | JSON da DataTable |
| `datatable.js` (subáreas) | GET | `/cms/datatable/sub_areas_diario` | JSON da DataTable |
| `index.js` (CMS) | POST | `/cms/diario/status` | JSON booleano |
| `generation-status.js` | GET | `/cms/ajax/diario-generation-status/{id}` | JSON de status/progresso |
| `areas.js` | GET | `/cms/area/{id}` | JSON com diário, áreas e permissões |
| `areas.js` | POST | `/cms/area` | criação de matéria |
| `areas.js` | PUT | `/cms/area/{id}` | atualização de matéria |
| `areas.js` | DELETE | `/cms/area/{id}` | exclusão de matéria |
| `areas.js` | PUT | `/cms/ajax/diario-oficial/{id}/sort` | reordenação |
| `config.js` | DELETE | `/cms/diario/configuracoes/header-img/{id}` | remoção da imagem de cabeçalho |
| `cover-image.js` | DELETE | `/cms/diario-oficial/{id}/cover-image` | remoção da capa |
| `diario_portal.js` | POST | `/diario-oficial/filtro` | coleção de edições |
| `viewer.js` | GET | `/diario-oficial/viewer/{id}/file-info` | tamanho e páginas |
| `viewer.js` | GET | `/diario-oficial/viewer/search?term=` | edições encontradas |
| `viewer.js` | GET | `/diario-oficial/viewer/{id}/search-pdf?term=` | páginas e trechos |

## 7. Exportações

| Formato | Como é gerado |
|---------|---------------|
| **PDF do diário** | `FPdfService` (TCPDF + FPDI), gravado em `storage/app/public/diario-oficial/content/{id}/pdf/diário-{edicao}.pdf` e servido por `DiarioController@show` com `Cache-Control: no-store` |
| **Download do PDF** | `GET /cms/diario-oficial/{id}?download=1` → header `Content-Disposition: attachment` |
| **PDF de anexo** | Convertido para JPEG pelo `PdfConverter` (Imagick + Ghostscript) e embutido no diário |
| **Texto extraído do PDF** | Ghostscript `txtwrite`, com cache JSON por edição |

Não há exportação Excel/CSV do diário no módulo.

## 8. Acessibilidade e usabilidade (observações do legado)

- O botão "Imprimir" (`#printPdf`) é referenciado pelo `create.blade.php` e pelo
  componente de preview, mas o markup do preview não cria esse elemento: o
  binding é um no-op.
- `v6/resources/views/portal/layouts/diario-oficial/show-pdf.blade.php` abre a
  tag `<body` sem o `>` de fechamento.
- `v6/resources/views/prefecture/contents/diario-oficial/form.blade.php` contém
  um `--}}` sem `{{--` de abertura, que é renderizado como texto literal.
- Os CSS de `pdf/style.blade.php` e de
  `prefecture/contents/components/preview/diario-oficial/style.blade.php`
  contêm seletores inválidos (`.pb-10, {`, `.pb-14, {`, `width: 180x;`).
