# Redesign UX da execução Alocação WMS — Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** Reorganizar a tela de execução da Alocação WMS para o operador em operação: confirmar fixo no rodapé, lista como única região rolável, sugestão colada no produto e placeholders orientados a bipe.

**Architecture:** Reestrutura o estado `em_andamento` do `item.php` em 3 regiões (scan-stack fixa, lista rolável, rodapé fixo) via CSS flex escopado a `#alocacaowms-item`. Move blocos no DOM (sugestão, confirmar) sem mudar a lógica do `item.js` (bind por id). Ajuste de cópia + i18n.

**Tech Stack:** PHP (view), CSS (no `<style>` do item.php), JS vanilla/jQuery (item.js), i18n `show()` + `linguagens/{pt-br,en,es}.json`.

## Global Constraints

- **Não alterar lógica de domínio:** `_processarCodigo`, `_setProdutoCodigo`, `_setLocalizacao`, `_selecionarItemPorElemento`, `_atualizarBotaoConfirmar`, `_enviarSugestao`, `_bindConfirmar`, roteamento do scanner — tudo intacto.
- Divulgação progressiva do manual JÁ existe (inputs `display:none` + tap revela) — preservar, não reimplementar.
- Bipar deve selecionar pelo bipe (já é assim) — preservar.
- Escopo CSS: tudo prefixado por `#alocacaowms-item` (não vazar pra outras telas do App).
- Estados `iniciar`/`concluido`/`erro` inalterados.
- i18n: chave = md5 do literal PT (auto-harvest); EN/ES adicionados em `linguagens/{en,es,pt-br}.json`.
- Sem harness de teste de DOM no repo → verificação por `php -l` + `node --check` + checagem de i18n + smoke manual.
- Commits terminam com: `Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>`

---

## File Structure

- **Modify:** `componentes/Missoes/Logistica/sinais/App/html/alocacaowms/item.php` — markup das 3 regiões + mover sugestão e confirmar + placeholders + CSS no `<style>`.
- **Modify:** `componentes/Missoes/Logistica/sinais/App/html/alocacaowms/item.js` — split do `txt.aguardando`.
- **Modify:** `linguagens/pt-br.json`, `linguagens/en.json`, `linguagens/es.json` — traduções das 2 strings novas.

---

## Task 1: Layout em 3 regiões — confirmar fixo no rodapé + lista rolável

**Files:**
- Modify: `componentes/Missoes/Logistica/sinais/App/html/alocacaowms/item.php` (bloco `em_andamento`, ~767-981, e `<style>`)

**Interfaces:**
- Consome: estrutura atual `#alocacaowms-item .app-container > header + .wms-progress-bar-wrap + main.app-conteudo`.
- Produz: `main.app-conteudo.wms-trabalho` com `.wms-scan-stack` (fixa) + `.wms-lista-scroll` (rola); botão `#btn-confirmar-alocacao` movido para `<div class="wms-confirmar-footer">` irmão de `<main>`, fixo no rodapé. Ids preservados (JS continua funcionando).

- [ ] **Step 1: Adicionar CSS das 3 regiões no `<style>` do item.php**

Localizar o fim do bloco `<style>` no `item.php` (antes de `</style>`) e adicionar:

```css
    /* ===== Layout 3 regiões (scan fixa / lista rola / rodapé fixo) ===== */
    #alocacaowms-item .app-container {
        display: flex;
        flex-direction: column;
        height: 100dvh;
        min-height: 100dvh;
    }
    #alocacaowms-item .app-cabecalho,
    #alocacaowms-item .wms-progress-bar-wrap {
        flex: none;
    }
    #alocacaowms-item .app-conteudo.wms-trabalho {
        flex: 1;
        min-height: 0;
        display: flex;
        flex-direction: column;
        overflow: hidden;
        padding-bottom: 0;
    }
    #alocacaowms-item .wms-scan-stack {
        flex: none;
    }
    #alocacaowms-item .wms-lista-scroll {
        flex: 1;
        min-height: 0;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        padding-bottom: 0.75rem;
    }
    #alocacaowms-item .wms-confirmar-footer {
        flex: none;
        position: sticky;
        bottom: 0;
        padding: 0.6rem 1.25rem calc(0.6rem + env(safe-area-inset-bottom));
        background: linear-gradient(180deg, rgba(15,17,26,0) 0%, var(--app-fundo, #0f111a) 35%);
        z-index: 5;
    }
    #alocacaowms-item .wms-confirmar-footer .wms-btn-confirmar {
        margin: 0;
    }
```

- [ ] **Step 2: Marcar o `<main>` do em_andamento e abrir a scan-stack**

No `item.php`, trocar a linha de abertura do main do em_andamento:

```php
        <main class="app-conteudo" style="padding-top: 0.25rem; padding-bottom: 6rem;">

            <!-- === Área de Bipagem dos 2 Códigos === -->
            <div style="padding: 0 1.25rem 0.5rem;">
```

por (adiciona classe `wms-trabalho`, remove o padding-bottom:6rem agora desnecessário, abre `.wms-scan-stack`):

```php
        <main class="app-conteudo wms-trabalho" style="padding-top: 0.25rem;">

            <div class="wms-scan-stack">

            <!-- === Área de Bipagem dos 2 Códigos === -->
            <div style="padding: 0 1.25rem 0.5rem;">
```

- [ ] **Step 3: Fechar a scan-stack e abrir a lista-scroll antes da busca**

No `item.php`, localizar o bloco do Confirmar + separador + busca (atual ~883-899):

```php
            <!-- Botão Confirmar -->
            <button type="button"
                id="btn-confirmar-alocacao"
                class="wms-btn-confirmar"
                disabled>
                <i class="bi bi-check-circle-fill"></i>
                <?= show('Confirmar alocação') ?>
            </button>

            <!-- Separador -->
            <div style="height: 1px; background: rgba(255,255,255,0.07); margin: 0.25rem 1.25rem 0.75rem;"></div>

            <!-- Busca nos itens -->
            <div class="wms-search-box">
```

e substituir por (fecha `.wms-scan-stack` ANTES do que era o confirmar; remove o confirmar e o separador daqui; abre `.wms-lista-scroll` na busca):

```php
            </div><!-- /.wms-scan-stack -->

            <div class="wms-lista-scroll">

            <!-- Busca nos itens -->
            <div class="wms-search-box">
```

- [ ] **Step 4: Fechar a lista-scroll e o main; adicionar o rodapé fixo com o confirmar**

No `item.php`, localizar o fim das listas + fechamento do main (atual ~979-983):

```php
            </div>
            <?php endif; ?>

        </main>

        <?php endif; /* fim dos estados */ ?>
```

e substituir por (fecha `.wms-lista-scroll`, fecha `<main>`, adiciona o `<div class="wms-confirmar-footer">` com o botão Confirmar — mesmo id/classe/atributos):

```php
            </div>
            <?php endif; ?>

            </div><!-- /.wms-lista-scroll -->
        </main>

        <div class="wms-confirmar-footer">
            <button type="button"
                id="btn-confirmar-alocacao"
                class="wms-btn-confirmar"
                disabled>
                <i class="bi bi-check-circle-fill"></i>
                <?= show('Confirmar alocação') ?>
            </button>
        </div>

        <?php endif; /* fim dos estados */ ?>
```

- [ ] **Step 5: Verificar sintaxe**

Run: `php -l componentes/Missoes/Logistica/sinais/App/html/alocacaowms/item.php`
Expected: `No syntax errors detected`

- [ ] **Step 6: Confirmar exatamente 1 botão confirmar e balanço de divs**

Run: `grep -c 'id="btn-confirmar-alocacao"' componentes/Missoes/Logistica/sinais/App/html/alocacaowms/item.php`
Expected: `1`

Run: `grep -c 'wms-scan-stack\|wms-lista-scroll\|wms-confirmar-footer' componentes/Missoes/Logistica/sinais/App/html/alocacaowms/item.php`
Expected: `6` (cada classe aparece no CSS e no markup — 2 menções de scan-stack abre/fecha + 1 css; lista-scroll abre/fecha + css; footer markup + css). Inspeção visual: garantir que cada `<div>` aberto foi fechado.

- [ ] **Step 7: Smoke manual + commit**

Recarregar Apache (`sudo -n systemctl reload apache2`), abrir `app/alocacaowms/<id>` no dev: confirmar fixo no rodapé; só a lista rola; header+scan+rodapé não saem da tela; bipar/limpar/confirmar funcionam.

```bash
git add componentes/Missoes/Logistica/sinais/App/html/alocacaowms/item.php
git commit -m "$(cat <<'EOF'
feat(app): execução Alocação WMS em 3 regiões (confirmar fixo no rodapé)

Scan fixa no topo, lista de itens como única região rolável, botão
Confirmar fixo no rodapé (sempre alcançável). CSS escopado a
#alocacaowms-item; ids preservados (sem mudança no item.js).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
EOF
)"
```

---

## Task 2: Sugestão de código de barras colada ao produto

**Files:**
- Modify: `componentes/Missoes/Logistica/sinais/App/html/alocacaowms/item.php`

**Interfaces:**
- Consome: `.wms-scan-stack` (Task 1), bloco `#wms-sugestao-area` existente.
- Produz: `#wms-sugestao-area` renderizado logo após o hint do produto (antes do card de Localização), dentro da scan-area. JS inalterado (alvos por id).

- [ ] **Step 1: Remover a sugestão da posição atual (depois da localização)**

No `item.php`, localizar o bloco da sugestão na posição atual (logo após o fechamento da `wms-scan-area`, ~833-852) e **recortá-lo** (remover daqui):

```php
            <!-- Sugestão de código de barras (aparece quando produto selecionado) -->
            <div class="wms-sugestao-area" id="wms-sugestao-area" style="display: none;">
                <button type="button" id="btn-abrir-sugestao" class="wms-sugestao-link">
                    <i class="bi bi-upc-scan"></i>
                    <?= show('Sugerir código de barras') ?>
                </button>
                <div id="wms-sugestao-form" style="display: none;">
                    <div class="wms-sugestao-form">
                        <input type="text"
                            id="wms-sugestao-input"
                            class="wms-sugestao-input"
                            placeholder="<?= htmlspecialchars(show('Digite ou bipe o código')) ?>"
                            autocomplete="off"
                            inputmode="text">
                        <button type="button" id="btn-sugestao-confirmar" class="wms-sugestao-btn" disabled>
                            <?= show('Sugerir') ?>
                        </button>
                    </div>
                </div>
            </div>
```

Após remover, o local deve ficar: fechamento do `</div>` da `wms-scan-area` seguido direto pelo campo Quantidade.

- [ ] **Step 2: Inserir a sugestão logo após o hint do produto**

No `item.php`, localizar o hint do produto e o início do campo Localização:

```php
                <!-- Hint: selecionar da lista -->
                <div class="wms-hint-lista" id="wms-hint-lista" style="display: none;">
                    <button type="button" id="btn-hint-lista">
                        <i class="bi bi-arrow-down-circle"></i>
                        <?= show('ou selecione da lista abaixo') ?> ↓
                    </button>
                </div>

                <!-- Campo Localização -->
```

e inserir o bloco da sugestão entre o hint e o campo Localização:

```php
                <!-- Hint: selecionar da lista -->
                <div class="wms-hint-lista" id="wms-hint-lista" style="display: none;">
                    <button type="button" id="btn-hint-lista">
                        <i class="bi bi-arrow-down-circle"></i>
                        <?= show('ou selecione da lista abaixo') ?> ↓
                    </button>
                </div>

                <!-- Sugestão de código de barras (aparece quando produto selecionado) -->
                <div class="wms-sugestao-area" id="wms-sugestao-area" style="display: none;">
                    <button type="button" id="btn-abrir-sugestao" class="wms-sugestao-link">
                        <i class="bi bi-upc-scan"></i>
                        <?= show('Sugerir código de barras') ?>
                    </button>
                    <div id="wms-sugestao-form" style="display: none;">
                        <div class="wms-sugestao-form">
                            <input type="text"
                                id="wms-sugestao-input"
                                class="wms-sugestao-input"
                                placeholder="<?= htmlspecialchars(show('Digite ou bipe o código')) ?>"
                                autocomplete="off"
                                inputmode="text">
                            <button type="button" id="btn-sugestao-confirmar" class="wms-sugestao-btn" disabled>
                                <?= show('Sugerir') ?>
                            </button>
                        </div>
                    </div>
                </div>

                <!-- Campo Localização -->
```

- [ ] **Step 2b: Garantir 1 só ocorrência (sem duplicar)**

Run: `grep -c 'id="wms-sugestao-area"' componentes/Missoes/Logistica/sinais/App/html/alocacaowms/item.php`
Expected: `1`

- [ ] **Step 3: Verificar sintaxe**

Run: `php -l componentes/Missoes/Logistica/sinais/App/html/alocacaowms/item.php`
Expected: `No syntax errors detected`

- [ ] **Step 4: Smoke + commit**

Recarregar Apache; selecionar um produto (bipe/lista) e confirmar que "Sugerir código de barras" aparece logo abaixo do card de Produto.

```bash
git add componentes/Missoes/Logistica/sinais/App/html/alocacaowms/item.php
git commit -m "$(cat <<'EOF'
feat(app): sugestão de código colada ao card de Produto na Alocação WMS

Move #wms-sugestao-area para logo após o produto (antes da localização),
onde o contexto mental está. JS inalterado (alvo por id).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
EOF
)"
```

---

## Task 3: Placeholders orientados a bipe + i18n

**Files:**
- Modify: `componentes/Missoes/Logistica/sinais/App/html/alocacaowms/item.php`
- Modify: `componentes/Missoes/Logistica/sinais/App/html/alocacaowms/item.js`
- Modify: `linguagens/pt-br.json`, `linguagens/en.json`, `linguagens/es.json`

**Interfaces:**
- Consome: campos `#produto-valor` / `#localizacao-valor`; objeto `txt` no item.js.
- Produz: placeholders "Bipe o produto" / "Bipe a localização" no load E no reset (limpar). Chaves i18n md5 preenchidas em PT/EN/ES.

- [ ] **Step 1: Trocar os placeholders no item.php**

No `item.php`, trocar o valor inicial do campo Produto:

```php
                        <div class="wms-scan-valor vazio" id="produto-valor"><?= show('Aguardando leitura...') ?></div>
```
por:
```php
                        <div class="wms-scan-valor vazio" id="produto-valor"><?= show('Bipe o produto') ?></div>
```

E o do campo Localização:
```php
                        <div class="wms-scan-valor vazio" id="localizacao-valor"><?= show('Aguardando leitura...') ?></div>
```
por:
```php
                        <div class="wms-scan-valor vazio" id="localizacao-valor"><?= show('Bipe a localização') ?></div>
```

- [ ] **Step 2: Separar `txt.aguardando` em dois no item.js**

No `item.js`, trocar:
```javascript
    var txt = {
        aguardando:        'Aguardando leitura...',
```
por:
```javascript
    var txt = {
        aguardandoProduto:     'Bipe o produto',
        aguardandoLocalizacao: 'Bipe a localização',
```

- [ ] **Step 3: Usar o texto certo em cada limpar**

No `item.js`, em `_limparProduto`, trocar:
```javascript
        $('#produto-valor').text(txt.aguardando).addClass('vazio');
```
por:
```javascript
        $('#produto-valor').text(txt.aguardandoProduto).addClass('vazio');
```

Em `_limparLocalizacao`, trocar:
```javascript
        $('#localizacao-valor').text(txt.aguardando).addClass('vazio');
```
por:
```javascript
        $('#localizacao-valor').text(txt.aguardandoLocalizacao).addClass('vazio');
```

- [ ] **Step 4: Verificar sintaxe**

Run: `php -l componentes/Missoes/Logistica/sinais/App/html/alocacaowms/item.php && node --check componentes/Missoes/Logistica/sinais/App/html/alocacaowms/item.js && echo OK`
Expected: `No syntax errors detected ...` + `OK`

Run: `grep -c "txt.aguardando\b" componentes/Missoes/Logistica/sinais/App/html/alocacaowms/item.js`
Expected: `0` (nenhuma referência órfã à chave antiga)

- [ ] **Step 5: Calcular as chaves md5 e adicionar i18n nos 3 idiomas**

Run: `php -r "echo md5('Bipe o produto').\"\n\".md5('Bipe a localização').\"\n\";"`
Anote as duas chaves (ex.: `<KEY_PROD>` e `<KEY_LOC>`).

Em `linguagens/pt-br.json`, adicionar (PT = o próprio literal):
```json
    "<KEY_PROD>": "Bipe o produto",
    "<KEY_LOC>": "Bipe a localização",
```
Em `linguagens/en.json`:
```json
    "<KEY_PROD>": "Scan the product",
    "<KEY_LOC>": "Scan the location",
```
Em `linguagens/es.json`:
```json
    "<KEY_PROD>": "Escanee el producto",
    "<KEY_LOC>": "Escanee la ubicación",
```
(Inserir como novas entradas válidas no objeto JSON — atenção à vírgula da entrada anterior.)

- [ ] **Step 6: Validar JSON dos 3 idiomas**

Run: `for f in pt-br en es; do php -r "json_decode(file_get_contents('linguagens/$f.json')); echo '$f: '.(json_last_error()===JSON_ERROR_NONE?'OK':'ERRO').\"\n\";"; done`
Expected: `pt-br: OK` / `en: OK` / `es: OK`

- [ ] **Step 7: Smoke + commit**

Recarregar Apache; conferir os cards mostrando "Bipe o produto"/"Bipe a localização" no load e após limpar; trocar idioma (se possível) e ver EN/ES.

```bash
git add componentes/Missoes/Logistica/sinais/App/html/alocacaowms/item.php \
        componentes/Missoes/Logistica/sinais/App/html/alocacaowms/item.js \
        linguagens/pt-br.json linguagens/en.json linguagens/es.json
git commit -m "$(cat <<'EOF'
feat(app): placeholders orientados a bipe na Alocação WMS

"Bipe o produto" / "Bipe a localização" no load e no reset (txt separado
por campo). i18n PT/EN/ES.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
EOF
)"
```

---

## Self-Review

**Spec coverage:**
- #3 rodapé fixo + lista rolável (CA 4, 5) → Task 1. ✔
- #2 sugestão colada no produto (CA 3) → Task 2. ✔
- #4 placeholders (CA 6) → Task 3. ✔
- Divulgação progressiva / bipe seleciona (CA 1, 2) → preservados, sem tarefa (intencional). ✔
- Estados iniciar/concluido/erro inalterados (CA 7) → nenhuma tarefa toca neles. ✔

**Placeholder scan:** Sem TBD/TODO. As únicas marcações `<KEY_PROD>`/`<KEY_LOC>` na Task 3 são valores calculados em runtime no Step 5 (md5), não placeholders de plano. ✔

**Type consistency:** `txt.aguardandoProduto`/`txt.aguardandoLocalizacao` definidos na Task 3 Step 2 e usados nos Steps 3; ids `#btn-confirmar-alocacao`, `#wms-sugestao-area`, `#produto-valor`, `#localizacao-valor` consistentes com o item.js existente. ✔

**Riscos conhecidos:**
- CSS flex escopado a `#alocacaowms-item` pode afetar os estados erro/concluido (mesmo container). Mitigação: o inner flex (scan-stack/lista-scroll/overflow) é escopado a `.wms-trabalho` (só em_andamento); o `height:100dvh` no `.app-container` é benigno para telas centradas.
- `100dvh` — usar `dvh` (viewport dinâmico) evita o pulo da barra de endereço no mobile; fallback implícito do browser para telas sem suporte é aceitável no contexto coletor.
