# Notícias — Views e UX

## 1. CMS — telas e arquivos Blade

Pasta: `v6/resources/views/prefecture/contents/noticias/`

| Arquivo | Linhas | Função |
|---|---|---|
| `index.blade.php` | 70 | Listagem (datatable). Cabeçalho com "Lista de Notícias", botão "Cadastrar Notícia" (`noticias.create`), botão "Categorias de Notícias" e o componente de exclusão em lote (`noticias.delete`) |
| `create.blade.php` | 59 | Wrapper do formulário de criação |
| `edit.blade.php` | 109 | Wrapper do formulário de edição (inclui galeria) |
| `form.blade.php` | 277 | Formulário completo (título, linha fina, texto, categoria, data, autor, fonte, destaque, galeria, secretaria, órgão) |
| `show.blade.php` | 30 | Pré-visualização |

Estrutura da listagem (`index.blade.php`):

```blade
@if (has_access(['noticias.create']))
    <a href="cadastrar/noticias" class="btn btn-success font-weight-bold btn-sm" role="button">
        <i class="fa fa-plus"></i> Cadastrar Notícia
    </a>
@endif
<table id="tabela_noticias" class="table table-striped w-100">
    <thead>
        <tr>
            <th>ID</th>
            <th>Título</th>
            <th width="10%">Status</th>
            <th class="text-center">Visualizações</th>
            <th class="text-center">Data de publicação</th>
            <th class="text-center">Categoria</th>
            <th class="text-center">Destaque</th>
            <th class="column-actions text-center vertical-bottom">Ações</th>
        </tr>
    </thead>
```

Scripts carregados (`index.blade.php`, seção `@section('other-scripts')`):

```blade
<script src="{{ url('assets/js/custom/utilities/deleteAll.js') }}"></script>
<script src="{{ asset('assets/js/custom/contents/noticias/datatables.js') }}"></script>
```

Layout do CMS: `admin.layouts.app` (AdminLTE 1.22 / Bootstrap 3).

## 2. CMS — JavaScript da datatable

Arquivo: `v6/public/assets/js/custom/contents/noticias/datatables.js`

| Coluna | Campo da view `noticias` | Render |
|---|---|---|
| Título | `titulo` | div com `padding:8px` |
| Status | `status_name_noticias` | "Publicado" / "Rascunho" em negrito |
| Visualizações | `visualizacoes` | `clicks` |
| Data | `data_publicacao` | `converterData()` monta `<span class="d-none">YYYY/MM/DD</span>` para ordenação |
| Categoria | `categoria` | nome da subcategoria |
| Destaque | `destaque` | `createDestaqueButton(destaque, data.id, data.edit)` |
| Ações | `data: null` | compartilhar no Facebook, botão de galeria (`editar/noticias/{id}#galeria`), editar e excluir |

O botão de galeria navega para `editar/noticias/{id}#galeria` — âncora usada
pelo formulário para focar a seção de anexos.

Arquivo auxiliar: `v6/public/assets/js/custom/contents/noticias/edit.js`
(manipulação da galeria no formulário de edição).

## 3. Portal — layouts

O template ativo vem de `configurations.key = 'layout'`
(`v6/app/Http/Traits/GetInformationsPrefectureTrait.php:92-102`) e é validado
contra a existência da view `portal.layouts.<template>.home.index`; se não
existir, a aplicação força o modo manutenção e responde 404.

| Layout | Pasta | Arquivos de notícias |
|---|---|---|
| `default` | `v6/resources/views/portal/layouts/default/pages/contents/noticias/` | `index.blade.php`, `show.blade.php`, `view.blade.php` |
| `modelo1` | `v6/resources/views/portal/layouts/modelo1/noticias/` | `index.blade.php`, `show.blade.php`, `tags.blade.php`, `ultimas-noticias.blade.php`, `noticias-categorias-ajax.blade.php`, `categorias-noticias/categorias-ajax.blade.php`, `layouts/layout1..3.blade.php`, `layouts-home/layout.blade.php` |
| `modelo2` | `.../modelo2/noticias/` | `index.blade.php`, `show.blade.php`, `ultimas-noticias.blade.php`, `noticias-categorias-ajax.blade.php`, `categorias-noticias/` |
| `modelo3` | `.../modelo3/noticias/` | `index.blade.php`, `show.blade.php`, `tags.blade.php`, `ultimas-noticias.blade.php`, `noticias-categorias-ajax.blade.php`, `categorias-noticias/` |
| `modelo4` | `.../modelo4/noticias/` | `index.blade.php`, `show.blade.php`, `tags.blade.php`, `ultimas-noticias.blade.php`, `noticias-categorias-ajax.blade.php`, `categorias-noticias/` |
| `modelo5` | `.../modelo5/noticias/` | `index.blade.php`, `show.blade.php`, `tags.blade.php`, `noticias-categorias-ajax.blade.php`, `categorias-noticias/`, `layouts/`, `layouts-home/`; na home: `.../modelo5/home/news/more-news/ultimas-noticias.blade.php`, `.../modelo5/home/destaques/carousel-noticias.blade.php`, `.../modelo5/home/destaques/noticias-destaque.blade.php` |
| `modelo6` | `.../modelo6/noticias/` | idem modelo2 |
| `newsbit` | `.../newsbit/noticias/` | `index.blade.php`, `layouts/` |

Componente compartilhado: `v6/resources/views/portal/components/secretarias/noticias.blade.php`
(bloco de notícias dentro da página de uma secretaria).

## 4. Portal — Home e carrossel

- `getContentsByParentCategory` (`v6/app/Http/Traits/NewsTrait.php:164-212`)
  monta a lista da home excluindo os itens já usados no carrossel.
- A quantidade de itens do carrossel é calculada por
  `lastNewsForLayout($layout, $carouselQuantity)`
  (`v6/app/Helpers/functions.php:1091-1128`):

  | Layout | Quantidade |
  |---|---|
  | `modelo1` | 6 |
  | `modelo2` | 7 |
  | `modelo3` | `10 - (5 - carousel)` |
  | `modelo4` | 3 |
  | `modelo5` | `8 - (5 - carousel)` |
  | `modelo6` | 4 |

- No `modelo5`, se `layouts.key = 'carousel-noticias'` tiver `section = 'tags'`,
  a listagem é filtrada por `highlights = true`
  (`v6/app/Http/Traits/NewsTrait.php:170-186`).

## 5. Portal — endpoints Ajax

| Endpoint | Nome | Retorno |
|---|---|---|
| `GET /noticias-ajax/{categorySlug}` | `noticia-categoria.index` | `['contents' => Collection, 'layout' => int]` |

Regras do endpoint (`v6/app/Http/Controllers/Portal/NewsController.php:111-135`):

- remove `categorySlugSession` da sessão antes de consultar
  (`session()->pull('categorySlugSession')`);
- só responde quando `request()->ajax()` é verdadeiro (caso contrário
  retorna `null` — resposta HTTP 200 vazia);
- substitui a imagem ausente pelo placeholder
  `storage/img/exemplos/exemplos/sem-imagem-min.png`;
- a consulta usa `byCategoryContentNews($slugCategory)` + data + status +
  `limit(quantidade_itens da categoria)`.

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

**Listagem (`/noticias`)**

- Se `configurations.key = 'noticias'` tem valor `0`, o portal entra em modo
  "agrupado": exibe uma faixa por subcategoria, com `quantidade_itens`
  matérias cada, ordenadas por `publication_date` decrescente.
- Caso contrário, exibe a listagem simples e lê
  `configurations.key = 'aviso_noticias'` para exibir o aviso de manutenção
  da editoria.

**Matéria (`/noticia/{slug}`)**

- Título, linha fina, autor, data de publicação, categoria.
- Corpo HTML vindo do Summernote (imagens já movidas para
  `storage/summernote-files/content/<slug>/<id>/`).
- Imagem de destaque (`archives.highlight = 1`).
- Galeria (`archives.highlight IS NULL`), ordenada por `order` (na v6) ou
  `created_at` (na v5 — ver `08-GAPS-E-DIVIDAS.md`).
- PDF inline (`archives.view_pdf = true`).
- Vídeo via `embedVideo($contentNew->linksUnique->link)`.

**Contador de cliques**: cada abertura executa `updateClicks()`; o valor
aparece na coluna "Visualizações" da datatable do CMS.

## 7. O que o operador vê

| Elemento | Origem |
|---|---|
| Coluna "Visualizações" | `contents.clicks` via view `noticias` |
| Selo "Publicado"/"Rascunho" | `contents.status` via view `noticias` |
| Botão de destaque | `createDestaqueButton()` -> `POST /cms/marcar-destaque` |
| Galeria | âncora `#galeria` no formulário de edição |
| Exclusão em lote | componente `prefecture.components.deleteByLoteSubmitButton` com rota `ajax.generic.content.deleteAll` |
| Auditoria | trilha `activity()` (cadastro, edição, exclusão, link, arquivo) |

## 8. Exportações

O módulo de notícias **não** possui exportação própria. A exportação de
conteúcidos vive em `ExportsContentTrait`
(`v6/app/Http/Traits/ExportsContentTrait.php`) e é usada por Publicações
(ver `../publicacoes/04-VIEWS-E-UX.md`).

## 9. Acessibilidade e responsividade

- As views do portal usam Bootstrap 4 com grid (`col-md-*`, `col-xs-*`).
- O CMS usa Bootstrap 3 (AdminLTE), com tabelas `table-striped` e colunas de
  ação com classe `column-actions`.
- As tabelas do CMS são carregadas via Ajax (Yajra DataTables), com
  paginação, busca e ordenação server-side na view SQL.
