# Comitê de Investimentos — Views e UX

## 1. Views do portal

O portal resolve o tema ativo pela chave `layout` da tabela `configurations`
(`v6/app/Http/Traits/GetInformationsPrefectureTrait.php:92`, helper
`getTemplateActived()`), e renderiza `portal.layouts.{layout}.comite-de-investimentos.*`.

### 1.1 Arquivos por tema

| Tema | `list` | `pub-nav` | `show` | `view` |
|---|---|---|---|---|
| `modelo1` | sim | sim | sim | sim |
| `modelo2` | sim | sim | sim | sim |
| `modelo3` | sim | sim | sim | sim |
| `modelo4` | sim | sim | sim | sim |
| `modelo5` | sim | sim | sim | sim |
| `modelo6` | sim | sim | sim | sim |
| `default` | **não** | **não** | **não** | **não** |

Caminho base: `v6/resources/views/portal/layouts/modelo1/comite-de-investimentos/`
(idem para `modelo2` a `modelo6`).

O tema `default` **não possui** as views do comitê; se a configuração `layout`
apontar para `default`, a chamada falha. Em compensação, `getTemplateActived()`
valida a existência de `portal.layouts.{layout}.home.index` e aborta com 404 —
mas o diretório `v6/resources/views/portal/layouts/default/` **não tem** a pasta
`home`, o que torna o tema `default` inutilizável para o portal inteiro.

### 1.2 `list.blade.php` — lista + filtros

`v6/resources/views/portal/layouts/modelo1/comite-de-investimentos/list.blade.php`

| Bloco | Conteúdo |
|---|---|
| Card de busca | Ícone de lupa + `select[name=ano]`, `select[name=mes]`, `input#search` e botões de limpar/enviar |
| Select de ano | Itera `$anos`; só mostra anos `<= date('Y')`; marca `selected` quando `$ano->ano == $anoSelecionado` |
| Select de mês | Itera `$meses` (só existe se houve filtro por ano); rótulo via `translateMonth($mes->mes)` |
| Campo de texto | `name="text"` com `id="search"`; valor `{{ $text or '' }}` |
| Campos ocultos | `sub_category` = `$category->slug`; `category` = `comite-de-investimentos` |
| Lista | `ul#pubs.jscroll`; cada item mostra `date('d/m/Y', publication_date)`, `$content->title` e 200 caracteres do texto (`str_limit(strip_tags(stripslashes($content->text)), 200)`) |
| Paginação | `{{ $contents->links() }}` |
| Vazio | "Nenhum resultado." |

Diferenças entre temas: `modelo3` e `modelo4` reestruturam o card de busca
(caixa lateral com borda colorida); `modelo1`, `modelo2`, `modelo5` e `modelo6`
usam o mesmo markup.

### 1.3 `pub-nav.blade.php` — menu de categorias

`v6/resources/views/portal/layouts/modelo1/comite-de-investimentos/pub-nav.blade.php`

- Itera `$categories` (subcategorias do comitê ordenadas por `order`).
- Cada item é link para `route('portal.comite-de-investimentos.show', $cat->slug)`.
- A categoria ativa recebe a classe `active`.
- O container recebe `scrollbar` quando há mais de 14 categorias.

### 1.4 `show.blade.php` — página de listagem

`v6/resources/views/portal/layouts/modelo1/comite-de-investimentos/show.blade.php`

- Estende `portal.layouts.modelo1.layout.layout`.
- Breadcrumb: `Breadcrumbs::view('portal.layouts.modelo1.layout.breadcrumb','category-comite-de-investimentos', $category)`.
- Carrega `/assets/vendor/portal/css/spinner.css` no bloco `other-links`.
- Inclui `pub-nav` e, dentro de `#include-list`, o partial `list`.
- Bloco `other-scripts` contém todo o JavaScript de paginação e filtros.

### 1.5 `view.blade.php` — leitura da ata

`v6/resources/views/portal/layouts/modelo1/comite-de-investimentos/view.blade.php`

| Elemento | Origem |
|---|---|
| Meta tags OpenGraph | `$content->title`, `strip_tags($content->text)`, `url()->full()` |
| Breadcrumb | `view-comite-de-investimentos` |
| Cabeçalho | `$content->categoryContents->name`, `$content->title` |
| Data | `date('d/m/Y', strtotime($content->publication_date))` e `date('H:i', strtotime($content->publication_date))` |
| Corpo | `{!! $content->text !!}` — HTML **sem escape** (Summernote) |
| Anexos | `@include('portal.components.view_pdf.files-list')` quando `count($archives) > 0 || $view_pdf != null` |
| Lateral | `@include('portal.layouts.modelo1.layout.sidebar.layout')` |

## 2. JavaScript do portal (filtros e paginação AJAX)

Definido inline no bloco `other-scripts` de `show.blade.php`:

| Função | Comportamento |
|---|---|
| `getPosts(page)` | AJAX GET `?page=&ano=&mes=&texto=`; substitui `#include-list`; grava `location.hash = page` |
| `getPostsByAno()` | AJAX GET `?ano=`; se o ano for vazio, `location.reload()` |
| `getPostsByMes()` | AJAX GET `?ano=&mes=` |
| `getPostsByTexto()` | AJAX GET `?ano=&mes=&texto=` |
| `apagaTexto()` | Limpa `#search` e re-filtra |
| `exibirBotaoCancelar()` | Exibe o botão "×" (X) |
| `$(window).on('hashchange')` | Refaz a consulta quando o `#` muda |

Durante a requisição, `#pub-content` recebe a classe `sk-loading` (spinner
`sk-spinner`); em caso de falha, um `alert('Os comitês de investimentos não puderam ser carregados.')`.

**Endpoints chamados:** apenas a própria rota (`.show`) com query string — não
há endpoint JSON dedicado.

**Ponto crítico:** a resposta AJAX do controller é
`Response::json(view("portal.layouts.{layout}.publicacoes.list")->render())`
(`v6/app/Http/Controllers/Portal/ComiteDeInvestimentosController.php:100-113`),
ou seja, o HTML devolvido vem da view de **Publicações**
(`v6/resources/views/portal/layouts/modelo1/publicacoes/list.blade.php`), e não
da `comite-de-investimentos/list.blade.php` usada no carregamento inicial. O
cidadão vê, portanto, **dois layouts diferentes** para a mesma listagem
(estático vs. AJAX).

## 3. Views do CMS

### 3.1 Conteúdos

| Arquivo | Função |
|---|---|
| `v6/resources/views/prefecture/contents/comite-de-investimentos/index.blade.php` | Listagem com DataTable `#tabela_comite_de_investimentos`; botões "Cadastrar Comitês de Investimentos" (`cadastrar/conteudo`), "Categorias de Comitês de Investimentos" (`route('cadastrar-categorias', 'comite-de-investimentos')`) e exclusão em lote |
| `v6/resources/views/prefecture/contents/comite-de-investimentos/create.blade.php` | Formulário; `Form::open(['route' => ['conteudo.index'], 'files' => true])` |
| `v6/resources/views/prefecture/contents/comite-de-investimentos/edit.blade.php` | Formulário de edição (mesmo partial `form`) |
| `v6/resources/views/prefecture/contents/comite-de-investimentos/form.blade.php` | Campos do conteúdo |

Campos do `form.blade.php`:

| Campo | Componente | Observações |
|---|---|---|
| `category_slug` | hidden | Valor de `$categoryContent->slug` |
| `category_contents_id` | `components.inputs.select` | **Obrigatório**; `data` = `$categoryContentSelect` (subcategorias) |
| `slug` | `components.inputs.input` | Exibido só em edição; mostra o "Link Permanente" (`url('comite-de-investimentos/'.$categoryContentSelect[0]->slug).'/'.$content->slug`); botão "Acessar" abre o portal em nova aba |
| `title` | `components.inputs.input` | Obrigatório; `maxlen` 150 (a validação exige max 120) |
| `publication_date` | `components.inputs.date` | Obrigatório; máscara `br-data-tempo`, formato `d/m/Y H:i` |
| `text` | `components.inputs.textarea` | Obrigatório; Summernote |
| Anexos | `components.inputs.archive` | `delete_function = deleteHighlightArchive`; "Tamanho máximo: 128MB" |

O checkbox de "Publicar" (`status`) está **comentado** no formulário do comitê
(bloco `{{-- bloco comentado --}}`), o que significa que o campo `status` não é enviado pelo
formulário — mas o `ContentController@store` grava `$request->get('status')`.

Scripts do formulário: `assets/js/custom/utilities/helpers/add_archive.js`,
Summernote (`assets/plugins/summernote/summernote.min.js`,
`summernote-pt-BR.js`, `summernote-image-atr.js`),
`assets/js/custom/utilities/richtext/summernote.js` e
`assets/js/custom/contents/noticias/edit.js` — **o JS de edição é o de Notícias**
(cópia).

### 3.2 Categorias

| Arquivo | Função |
|---|---|
| `v6/resources/views/prefecture/category-contents/comite-de-investimentos/create.blade.php` | Formulário + tabela ordenável `#dataTableListContentsConf` |
| `v6/resources/views/prefecture/category-contents/comite-de-investimentos/edit.blade.php` | Edição de subcategoria |
| `v6/resources/views/prefecture/category-contents/comite-de-investimentos/form.blade.php` | Campo `name` (máx. 120) e exibição do pai |

A ordenação por arraste envia `sortable_data[]` para
`route('ajust.categorias')` (`v6/routes/basepro.php:161`).

### 3.3 DataTable do CMS

`v6/public/assets/js/custom/contents/comite-de-investimentos/datatables.js`:

```javascript
runDatatables('comite_de_investimentos', collums, true, 'ASC', null, true);
```

- URL montada em `v6/public/assets/js/custom/utilities/table.js:183`:
  `/cms/datatable/${url}` → `/cms/datatable/comite_de_investimentos`.
- Colunas: `value` (numeração), coluna de seleção (delete em lote),
  `titulo`, `categoria`, `data_publicacao` e ações.
- Ação "Acessar comitê de investimento": link para
  `/comite-de-investimentos/${categoria_slug}/${slug}` em nova aba (usa as
  colunas adicionadas na migration de nov/2024).
- Ação "Editar": `editar/comite-de-investimentos/${id}`.
- Ação "Excluir": `DELETE /cms/conteudo/${id}`.
- Exportação: Excel, PDF e CSV (botões padrão de `table.js`), com o título
  "Prefeitura de {cidade} - {data}".

## 4. O que o cidadão vê

1. Breadcrumb "Home > Comitê de Investimentos > {categoria}".
2. Menu lateral com as subcategorias do comitê.
3. Card de busca com ano, mês e texto.
4. Lista de atas com data, título e resumo de 200 caracteres.
5. Paginação e indicador de "Nenhum resultado." quando vazio.
6. Página da ata com título, data/hora, texto rico e anexos/PDF.
7. A rota `/comite-de-investimentos` não tem página própria: sempre redireciona.

## 5. O que o operador vê

1. Item de menu "Comitê de Investimentos" (ícone `balance-scale`), habilitado
   apenas se `modulos.status = true`.
2. Listagem DataTable com colunas ID, Título, Categoria, Data de publicação e
   Ações; linhas com `category` vazia são ignoradas.
3. Formulário único para create/edit.
4. Tela de categorias com ordenação por arraste.

## 6. Exportações

| Contexto | Formato | Como é gerado |
|---|---|---|
| CMS (DataTable) | Excel, PDF, CSV | DataTables Buttons (client-side), em `v6/public/assets/js/custom/utilities/table.js`; exclui a coluna de ações (`.column-actions`) |
| Portal | — | Não há exportação no portal |

## 7. Assets

| Asset | Caminho | Uso |
|---|---|---|
| CSS do spinner | `v6/public/assets/vendor/portal/css/spinner.css` | Indicador de carregamento do portal |
| CSS do comitê | — | Não há CSS específico do comitê |
| JS do comitê (CMS) | `v6/public/assets/js/custom/contents/comite-de-investimentos/datatables.js` | Colunas do DataTable |
| JS genérico | `v6/public/assets/js/custom/utilities/table.js` | `runDatatables`, `createBTN`, `createSingleButton` |
| JS de exclusão | `v6/public/assets/js/custom/utilities/deleteAll.js` | Exclusão em lote |
| JS de ajax | `v6/public/assets/js/custom/utilities/functions.js` | `myFetch` |
