# Notícias (V2) — Views e UX

> **Slug:** `publicacoes-noticias` · **Versão analisada:** V2.
>
> Caminhos relativos a `lotep/`. As views são registradas sob o namespace `v2-noticias` por `loadViewsFrom()` no `V2ServiceProvider` (`V2/Core/Providers/V2ServiceProvider.php:120`).

---

## 1. Inventário de views

| Arquivo | Linhas | Função |
|---|---|---|
| `V2/Modules/Publicacoes/Noticias/Views/cms/index.blade.php` | 423 | Listagem do CMS com filtros, contadores, cartões agrupados por categoria, modal de super-destaque. |
| `V2/Modules/Publicacoes/Noticias/Views/cms/archived.blade.php` | 124 | Lista de arquivadas com ação de reativar. |
| `V2/Modules/Publicacoes/Noticias/Views/cms/categories.blade.php` | 199 | CRUD de categorias em tabela + modal. |
| `V2/Modules/Publicacoes/Noticias/Views/cms/config/index.blade.php` | 273 | Aprovadores (com vigência), lista de usuários e editor de `sidebar_items`. |
| `V2/Modules/Publicacoes/Noticias/Views/cms/create.blade.php` | 33 | Casca de criação; inclui o editor. |
| `V2/Modules/Publicacoes/Noticias/Views/cms/edit.blade.php` | 32 | Casca de edição; inclui o editor. |
| `V2/Modules/Publicacoes/Noticias/Views/cms/preview.blade.php` | 104 | Preview dentro do layout do CMS, com banner de rascunho e token. |
| `V2/Modules/Publicacoes/Noticias/Views/cms/preview-iframe.blade.php` | 308 | HTML standalone para o iframe do editor; escuta `postMessage`. |
| `V2/Modules/Publicacoes/Noticias/Views/cms/includes/_editor-content.blade.php` | 501 | Formulário completo em 4 blocos + ações + histórico + JS de tags/slug. |
| `V2/Modules/Publicacoes/Noticias/Views/cms/includes/form.blade.php` | 95 | Campos de SEO (versão alternativa, include legado). |
| `V2/Modules/Publicacoes/Noticias/Views/cms/includes/scripts.blade.php` | 325 | Slug, copiar preview, SEO automático, modal de rejeição, confirmação, cópia do token. |
| `V2/Modules/Publicacoes/Noticias/Views/cms/includes/styles.blade.php` | 889 | CSS do editor/listagem. |
| `V2/Modules/Publicacoes/Noticias/Views/cms/includes/_confirm-modal.blade.php` | 47 | Modal genérico de confirmação. |
| `V2/Modules/Publicacoes/Noticias/Views/portal/index.blade.php` | 315 | Listagem pública com filtro client-side, paginação, estado vazio e JSON-LD `CollectionPage`. |
| `V2/Modules/Publicacoes/Noticias/Views/portal/show.blade.php` | 551 | Matéria: breadcrumb, capa, corpo, tags, compartilhamento, galeria, relacionadas, prev/next e JSON-LD `NewsArticle`. |
| `V2/Modules/Publicacoes/Noticias/Views/emails/notification-content.blade.php` | 108 | Corpo do e-mail para aprovadores. |

Assets:

| Arquivo | Uso |
|---|---|
| `V2/Modules/Publicacoes/Noticias/assets/portal-noticias.css` | Fonte versionada do CSS da listagem. |
| `V2/Modules/Publicacoes/Noticias/assets/portal-noticias-show.css` | Fonte versionada do CSS da matéria/iframe. |
| `public/V2/assets/css/modules/noticias/portal-noticias.css` | Cópia servida publicamente; usada com `filemtime()` como cache-buster. |
| `public/V2/assets/css/modules/noticias/portal-noticias-show.css` | Cópia servida usada pela matéria e pelo iframe. |

## 2. Layouts

| Layout | Caminho | Quando entra |
|---|---|---|
| CMS | `V2/layouts/cms/layouts/app.blade.php` (namespace `v2-cms`) | Todas as views `cms/*`; recebe `title` e `pageIcon`. |
| Portal | `V2/layouts/portal/app-layout.blade.php` (namespace `v2-portal`) | `portal/index` e `portal/show`; recebe `pageTitle`, `pageDescription`, `coverImage`, `schemas`, flags de header/footer/acessibilidade. |
| Standalone | nenhum | `V2/Modules/Publicacoes/Noticias/Views/cms/preview-iframe.blade.php` gera documento HTML completo, sem layout. |

O portal injeta os schemas no `<head>` via layout; a matéria monta `NewsArticle` em PHP no topo da view (`V2/Modules/Publicacoes/Noticias/Views/portal/show.blade.php:44-113`). A listagem declara `CollectionPage` (`V2/Modules/Publicacoes/Noticias/Views/portal/index.blade.php:12-22`).

## 3. CMS — o que o operador vê

### 3.1 Listagem (`V2/Modules/Publicacoes/Noticias/Views/cms/index.blade.php`)

- Cabeçalho com `<p>{{ $news->total() }} registro(s) encontrado(s)</p>`.
- Barra de status clicável: Rascunho, Pendente, Publicado, Rejeitado e Arquivadas, com contadores de `News::getStatsByStatus()` (5 consultas por render).
- Filtros: busca textual, status, categoria e tag; a busca tem debounce de 300 ms no cliente e submete o formulário.
- Cartões compactos com capa, status, estrela/raio (destaques), título, data, autor, até 3 tags e ações: editar, ver no portal, destacar e arquivar.
- Agrupamento visual por categoria (`groupBy` na coleção do paginator) com fundos alternados; categorias vazias não aparecem.
- Modal de super-destaque lista **todas** as publicadas (`$allPublished`) em um `<select size="8">`.

### 3.2 Editor (`V2/Modules/Publicacoes/Noticias/Views/cms/includes/_editor-content.blade.php`)

Quatro blocos:

1. **Dados Críticos** — título, slug (com botão de regenerar e link "Ver no Portal" quando publicado), categoria (select com `optgroup` por categoria raiz e filhos) e tags (badges + campo livre com busca/criação).
2. **Metadados** — responsável, fonte, botão SEO (collapse), autor/data de criação, última edição e data de publicação.
3. **Conteúdo** — duas colunas: resumo + editor TipTap (`v2-service-contentricheditor::components.forms.content-rich-editor`); capa (`media-input`) e iframe de preview ao vivo.
4. **Galeria** — `media-group-input` com até 20 arquivos, `name="gallery_ids"`.

Ações: Cancelar, Arquivar (com modal), **Salvar Rascunho** e **Publicar**. Não há botão de "Enviar para aprovação" nem de "Aprovar/Rejeitar" no editor — as rotas existem, mas a UI não as expõe nesta pasta.

### 3.3 Preview

- `V2/Modules/Publicacoes/Noticias/Views/cms/preview.blade.php`: layout do CMS, banner amarelo quando `status !== published`, exibe o token (`.draft-token-display`, clicável para copiar via JS) e links para abrir no portal ou para a versão publicada.
- `V2/Modules/Publicacoes/Noticias/Views/cms/preview-iframe.blade.php`: documento próprio com CSS do portal, banner de preview, capa, meta, corpo e galeria com lightbox. Escuta `contentRichPreviewUpdate` e `previewUpdate` (`V2/Modules/Publicacoes/Noticias/Views/cms/preview-iframe.blade.php:235-242`). O emissor é `V2/Services/ContentRichEditor/Assets/js/content-rich-editor.js:64`, que publica o HTML atualizado no `postMessage`.

### 3.4 Categorias e configurações

- Categorias: tabela com nome, slug, subcategorias e ações; categorias `is_system` mostram cadeado e não têm botões.
- Configurações: seleção de usuário para aprovador, datas de vigência, remoção; editor dinâmico de itens de sidebar (label + URL).

## 4. Portal — o que o cidadão vê

### 4.1 Listagem

- Breadcrumb, título "Noticias", busca e pills de categoria.
- Busca e pills operam **client-side** sobre os cartões já renderizados (`V2/Modules/Publicacoes/Noticias/Views/portal/index.blade.php:222-305`). A paginação é **server-side** e preserva a query string (`$allNews->appends(request()->query())`).
- Consequência: com 13 notícias e página de 12, buscar um termo da 13ª não a encontra enquanto ela não estiver na página atual. O filtro por categoria/tag também só filtra o conjunto visível.
- Estado vazio com botão "Limpar filtros"; estado sem publicações com "Volte mais tarde".
- Cada cartão exibe capa em `<picture>` (`v2-service-media::components.picture`), data, título e resumo truncado em 200 caracteres.

### 4.2 Matéria

- Breadcrumb `Inicio > Noticias > título` com microdados `BreadcrumbList`.
- Banner "Modo Preview" quando `previewMode`.
- Título, subtítulo, data/hora, autor, categoria.
- Capa 16:9 sem `loading=lazy` e com prioridade alta (LCP) — o componente `picture` recebe `'lazy' => false`.
- Corpo: HTML do AST; se vazio, cai para subtítulo; se também vazio, "Nenhum conteudo disponivel."
- Tags, botões de compartilhamento (Facebook, Twitter/X, WhatsApp, copiar link) e galeria sempre presente (quando a relação foi carregada), com lightbox controlado por JS.
- Relacionadas por tag (até 4) com fallback para publicações recentes.
- Navegação anterior/próxima com `rel="prev"`/`rel="next"` e `aria-label` ("Notícia anterior: " . $titulo).
- Botão "Voltar para Noticias".

## 5. JavaScript e endpoints

| Onde | Recurso | Endpoint/evento |
|---|---|---|
| `V2/Modules/Publicacoes/Noticias/Views/cms/includes/scripts.blade.php` | Slug automático, regenerar, copiar link de preview, SEO auto-preenchido, modal de rejeição, confirmação genérica, cópia do token | Nenhum (DOM local). |
| `V2/Modules/Publicacoes/Noticias/Views/cms/index.blade.php` | Busca com debounce; `change` de status/categoria/tag submete o form | `GET /cms/noticias` |
| `V2/Modules/Publicacoes/Noticias/Views/cms/index.blade.php` | Toggle de destaque via `fetch` com `X-CSRF-TOKEN` | `POST /cms/noticias/{id}/toggle-highlight` |
| `V2/Modules/Publicacoes/Noticias/Views/cms/index.blade.php` | Modal de super-destaque submete form para a rota | `POST /cms/noticias/set-super-highlight` |
| `V2/Modules/Publicacoes/Noticias/Views/cms/includes/_editor-content.blade.php` | Tags (adicionar/remover), slug, cópia de token | Local; tags viram `tags[]` no POST |
| `V2/Modules/Publicacoes/Noticias/Views/cms/preview-iframe.blade.php` | `message` → substitui HTML e título | `contentRichPreviewUpdate`, `previewUpdate` |
| `V2/Modules/Publicacoes/Noticias/Views/portal/index.blade.php` | Filtro client-side e "limpar filtros" | Nenhum; não há chamada AJAX |
| `V2/Modules/Publicacoes/Noticias/Views/portal/show.blade.php` | Lightbox da galeria, copiar link, `message` para atualização de preview | `contentRichPreviewUpdate` |

Erros de rede no toggle de destaque apenas restauram o HTML do botão (`catch`); não há toast. O envio de formulário não usa `fetch` — é navegação completa.

## 6. Exportações

Não há exportação Excel/PDF/CSV no módulo.

## 7. Acessibilidade e mídia (observações)

- Há esforço consistente de ARIA: `aria-label` em ícones e ações, `aria-current`, `aria-pressed`, `role="search"`, skip links e `aria-hidden` em ícones decorativos.
- A galeria usa `<button>` com `aria-label` "Ampliar imagem N de M", mas o lightbox não implementa foco preso nem retorno de foco explícito no markup analisado.
- A matéria usa `<time datetime>` com ISO-8601; o CMS exibe datas em `d/m/Y`.
- Imagens passam pelo componente `picture` (AVIF/WebP), com `alt` vindo de `alt_text` e fallback para o título.
- Há CSS e JS **inline** nas views (`@push('styles')`, `@push('scripts')`, `onclick` no botão de copiar). No V7 isso conflita com CSP sem inline (ADR-022) e deve migrar para Vite/handlers registrados.
- O iframe usa `sandbox="allow-scripts allow-same-origin"` (`V2/Modules/Publicacoes/Noticias/Views/cms/includes/_editor-content.blade.php:283`), combinação que anula parte do sandbox quando o conteúdo é same-origin.
