# Portal — Visualização Pública

## Arquivos

- `resources/views/portal/layouts/diario-oficial/index.blade.php` — Listagem
- `resources/views/portal/layouts/diario-oficial/show-pdf.blade.php` — Visualizador
- `public/assets/js/custom/contents/diario-oficial/diario_portal.js` — Filtros
- `public/assets/js/custom/portal/diario-oficial/viewer.js` — Viewer
- `public/assets/css/portal/diario-oficial-viewer.css` — Estilos

---

## Listagem Pública (`index.blade.php`)

### URL: `GET /diario-oficial`

### Layout

Estende `portal.layouts.{model}.layout.layout` (template ativo do portal).

### Estrutura

```
┌─────────────────────────────────────────────────┐
│  Filtrar Diários              DIÁRIO OFICIAL    │
│  ┌─────────────────┐         ┌───────────────┐  │
│  │ Data início     │         │ Edição 1234   │  │
│  │ Data final      │         │ 01/01/2025    │  │
│  │ Palavra-chave   │         │ [Visualizar]  │  │
│  │ Edição          │         ├───────────────┤  │
│  │ [Filtrar]       │         │ Edição 1233   │  │
│  └─────────────────┘         │ 28/12/2024    │  │
│                              │ [Visualizar]  │  │
│                              └───────────────┘  │
└─────────────────────────────────────────────────┘
```

### Filtros

| Filtro | Tipo | ID |
|--------|------|----|
| Data de início | `date` | `DataINI` |
| Data final | `date` | `DataFIM` |
| Palavra-chave | `text` | `Search_termo` |
| Edição | `text` (numérico) | `Search_edicao` |

Os filtros são processados via JavaScript (`diario_portal.js`) que faz uma requisição POST para `/diario-oficial/filtro`.

### Scripts Carregados

```blade
<script src="{{ url('assets/js/custom/utilities/functions.js') }}"></script>
<script src="{{ url('assets/js/custom/contents/diario-oficial/diario_portal.js') }}" defer></script>
```

---

## Visualizador PDF (`show-pdf.blade.php`)

### URL: `GET /diario-oficial/{id}`

### Layout (HTML independente — não estende layout do portal)

Página autônoma com:

```
┌─────────────────────────────────────────────────────┐
│  ┌────────────────────────┐ ┌─────────────────────┐ │
│  │                        │ │  [Logo]              │ │
│  │                        │ │  DIÁRIO OFICIAL      │ │
│  │      PDF EMBED         │ │  Nome da Prefeitura  │ │
│  │      (object/embed)    │ │─────────────────────│ │
│  │                        │ │  Tamanho: 2.5 MB    │ │
│  │                        │ │  Descrição: EDIÇÃO 5 │ │
│  │                        │ │  Publicação: 01/01  │ │
│  │                        │ │─────────────────────│ │
│  │                        │ │  Assinatura Digital  │ │
│  │                        │ │  Responsável: João  │ │
│  │                        │ │  E-mail: ...        │ │
│  │                        │ │  Lei: ...           │ │
│  │                        │ │─────────────────────│ │
│  │                        │ │  Pesquisar Termo    │ │
│  │                        │ │  [input busca]      │ │
│  │                        │ │─────────────────────│ │
│  │                        │ │  [◄ Anterior]       │ │
│  │                        │ │  [Próxima ►]       │ │
│  └────────────────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────┘
```

### Componentes

| Componente | Descrição |
|-------------|-----------|
| `<embed>` | PDF viewer nativo do navegador |
| Sidebar | Informações + navegação |
| Assinatura Digital | Dados do certificado |
| Navegação | Edições anterior/próxima |
| Busca | Busca por termo no diário |

### Informações Exibidas

- **Tamanho do arquivo** (calculado via AJAX → `fileInfo`)
- **Descrição**: Edição do diário
- **Data de publicação**
- **Assinatura Digital**: Data, Responsável, E-mail, Lei validatória

### Busca (AJAX)

Endpoint: `GET /diario-oficial/viewer/search?term=...`

```php
public function search(Request $request) {
    // Busca ILIKE em: conteudo, titulo, edicao, lei_validadora, autor
    // Retorna JSON com resultados (id, edicao, data_publicacao)
}
```

### Navegação entre Edições

```php
$previousEdition = Diario::where('data_publicacao', '<', $diario->data_publicacao)
    ->where('status', 1)->orderBy('data_publicacao', 'desc')->first();

$nextEdition = Diario::where('data_publicacao', '>', $diario->data_publicacao)
    ->where('status', 1)->orderBy('data_publicacao', 'asc')->first();
```

### Geração sob Demanda

Se o PDF não existir em disco, é gerado automaticamente:

```php
if (!file_exists(public_path($pdfPath))) {
    $this->repository->generatePDF($id, true);
}
```

### Scripts

```javascript
const diarioData = {
    id: {{ $diario->id }},
    edicao: '{{ $diario->edicao }}',
    previousEdition: @json($previousEdition),
    nextEdition: @json($nextEdition),
    pdfPath: '{{ asset($pdfPath) }}',
    // ...
};

const apiUrls = {
    search: '{{ route('portal-diario.search', ':id') }}',
    fileInfo: '{{ route('portal-diario.file-info', ':id') }}',
};
```

### CSS

`public/assets/css/portal/diario-oficial-viewer.css`

Estilos específicos para:
- Layout do visualizador (flex container)
- Sidebar com informações
- Botões de navegação
- Responsividade

---

## JavaScript do Portal

### `diario_portal.js`

Gerencia os filtros da listagem pública:
- Captura valores dos campos
- Faz requisição POST para `/diario-oficial/filtro`
- Renderiza resultados na `<ul id="diarioZona">`
- Gerencia paginação (links)

### `viewer.js`

Gerencia o visualizador PDF:
- Calcula e exibe tamanho do arquivo (fetch `fileInfo`)
- Implementa busca por termo no PDF
- Navegação entre edições (anterior/próxima)
- Atualiza URLs sem reload
