# 05 — Mobile App (React Native)

## Estrutura de Arquivos

```
mobile-app/
├── App.js                    ← Raiz do app; configuração de navegação
├── app.json                  ← Configuração Expo (nome, ícone, permissions)
├── index.js                  ← Entry point registra App
├── config.js                 ← URL da API (API_URL)
├── metro.config.js           ← Configuração do bundler
│
├── context/
│   └── MenuContext.js        ← Contexto global: usuário logado + menu state
│
├── services/
│   └── NotificationService.js ← Registro de token e handler de notificações
│
├── components/
│   ├── GlobalMenu.js         ← Menu lateral slide-out (Modal)
│   ├── MenuButton.js         ← Botão hamburger hamburguer (abre GlobalMenu)
│   ├── BackButton.js         ← Botão voltar customizado
│   ├── SearchButton.js       ← Botão de busca que navega para SearchResults
│   ├── HelpButton.js         ← Botão de ajuda contextual
│   ├── HelpModal.js          ← Modal de ajuda com textos por screenKey
│   ├── ProjectCard.js        ← Card de projeto (no Dashboard)
│   └── ProjectGanttChart.js  ← Gráfico de Gantt do projeto
│
├── screens/
│   ├── LoginScreen.js
│   ├── DashboardScreen.js
│   ├── TaskListScreen.js
│   ├── TaskDetailsScreen.js
│   ├── CreateTaskScreen.js
│   ├── ProjectDetailsScreen.js
│   ├── CreateProjectScreen.js
│   ├── MyProjectsListScreen.js
│   ├── DemandDetailsScreen.js
│   ├── DemandListScreen.js
│   ├── CreateDemandScreen.js
│   ├── SearchResultsScreen.js
│   ├── NotificationsScreen.js
│   ├── CostApprovalScreen.js
│   ├── ChangePasswordScreen.js
│   ├── SetupRequiredScreen.js
│   ├── SettingsScreen.js
│   └── settings/
│       ├── ConstantsScreen.js
│       ├── StructuresScreen.js
│       ├── UsersScreen.js
│       ├── ThemesScreen.js
│       ├── CostCategoriesScreen.js
│       └── CostCentersScreen.js
│
└── assets/                   ← Ícones, imagens, splash screen
```

---

## App.js — Raiz da Aplicação

### Responsabilidades
1. **Wrap global** com `MenuProvider` (contexto de menu + usuário)
2. **NavigationContainer** com `ref` para navegação programática (deep links de notificações)
3. **Stack.Navigator** com todas as rotas registradas
4. **setupNotificationHandler** conectado ao `navigationRef` via `useEffect`
5. **GlobalMenu** renderizado fora do navigator para acessibilidade universal

### Rotas Registradas (Stack Navigator)

| Route Name | Tela | Observações |
|------------|------|-------------|
| `Login` | LoginScreen | Rota inicial |
| `Dashboard` | DashboardScreen | `gestureEnabled: false` (não volta para Login) |
| `SetupRequired` | SetupRequiredScreen | Mostrado se BD sem configuração |
| `TaskList` | TaskListScreen | Recebe `type`, `color`, `title` |
| `ProjectDetails` | ProjectDetailsScreen | Recebe `demanda_id` |
| `TaskDetails` | TaskDetailsScreen | Recebe `tarefa_id` |
| `CostApproval` | CostApprovalScreen | Para aprovação de custos |
| `CreateTask` | CreateTaskScreen | Recebe `user`, `demanda_id` |
| `CreateProject` | CreateProjectScreen | Recebe `user` |
| `CreateDemand` | CreateDemandScreen | Recebe `user` |
| `ChangePassword` | ChangePasswordScreen | Recebe `user` |
| `DemandDetails` | DemandDetailsScreen | Recebe `tarefarapida_id` |
| `DemandList` | DemandListScreen | Recebe `user` |
| `MyProjectsList` | MyProjectsListScreen | Recebe `user` |
| `SearchResults` | SearchResultsScreen | Recebe `query` |
| `Notifications` | NotificationsScreen | — |
| `Settings` | SettingsScreen | |
| `SettingsConstants` | ConstantsScreen | |
| `SettingsStructures` | StructuresScreen | |
| `SettingsUsers` | UsersScreen | |
| `SettingsThemes` | ThemesScreen | |
| `SettingsCostCategories` | CostCategoriesScreen | |
| `SettingsCostCenters` | CostCentersScreen | |

---

## Contexto Global (MenuContext)

### Estado Gerenciado
```js
isMenuOpen: boolean        // Visibilidade do menu lateral
userData: Object|null      // Dados do usuário logado
clienteAtual: Object|null  // Cliente atual { codigo, nome }
```

### Funções Expostas
```js
toggleMenu()   openMenu()   closeMenu()
setUserData(user)           setClienteAtual(cliente)
logout()  // Limpa userData e clienteAtual
```

### Acesso via Hook
```js
const { userData, openMenu, logout } = useMenu();
```

---

## Componentes

### `GlobalMenu`
Menu lateral em `Modal`, abre da direita. Largura = 75% da tela.

**Navegações disponíveis:**
- Dashboard (sempre)
- Criar Projeto (sempre)
- Criar Demanda (sempre)
- Alterar Senha (sempre)
- Configurações (somente `userData.admin == 1`)
- Sair (logout com confirmação `Alert`)

**Comportamento especial:**
- `Login` → logout + `navigation.reset()` para prevenir voltar
- `Placeholder` → Alert "Em breve"
- Toca fora (backdrop) → fecha menu

---

### `ProjectCard`
Card de projeto exibido no dashboard.

**Props:** `project`, `onPress`, `aVencer`

**Conteúdo exibido:**
- Nome do projeto (descricao)
- Status com badge colorido
- Progresso (barra visual)
- Data de prazo (com cor: verde/amarelo/vermelho baseado em `a_vencer`)
- Total de tarefas e tarefas concluídas

---

### `ProjectGanttChart`
Renderiza gráfico de Gantt para o projeto.

**Props:** `tasks` (array de tarefas), `projeto` (dados do projeto)

**Tecnologias:** `react-native-svg`, `react-native-view-shot`, `expo-print`, `expo-sharing`

**Funcionalidades:**
- Barra de tempo proporcional por tarefa
- Cores por status
- Exportação como PDF (via View Shot + Print)
- Compartilhamento nativo

---

### `SearchButton`
Botão de lupa que navega para `SearchResultsScreen`.

**Props:** `user`

---

### `HelpButton` + `HelpModal`
Botão de `?` contextual que abre modal com texto de ajuda por tela.

**Props (HelpButton):** `screenKey` (ex: `"dashboard"`, `"tasks"`, `"project"`)

---

## Screens — Detalhes

### `LoginScreen`
**Estado:** `username`, `password`, `loading`, `clientModalVisible`, `availableClients`, `usuarioGlobalId`

**Fluxo:**
1. `handleLogin` → `POST /pre_login.php`
2. Se múltiplos clientes → exibe `Modal` de seleção
3. `completeLogin` → `POST /login.php` → armazena user no `MenuContext`
4. Chama `registerForPushNotifications` em background
5. `navigation.replace('Dashboard', { user })`

---

### `DashboardScreen`
**Estado:** `counts` (objeto com todos os cards), `myProjects`, `unreadNotifications`, `setupChecked`, `highlightedKeys`

**Funcionalidades:**
- Cards clicáveis por tipo de tarefa/demanda
- `useFocusEffect` → recarrega dados ao voltar para a tela
- Cache local `dashboardCache` por `usuario_id` → evita flickering
- Animação de highlight quando um count muda
- Sino de notificações com badge de contagem não lida
- Botão de refresh manual
- `HelpButton` contextual

---

### `TaskListScreen`
**Props recebidas:** `user`, `type`, `color`, `title`, `filter`

**Funcionalidades:**
- Lista tarefas do tipo recebido via `/tasks.php`
- Filtros: Todas, Expiradas, A Vencer
- Modal de observação ao clicar em tarefa INBOX (para distribuir)
- Navega para `TaskDetails` ou `DemandDetails`
- Pull-to-refresh
- Layout de card com status_color, prazo, responsável

---

### `TaskDetailsScreen`
A tela mais complexa da aplicação (~55KB).

**Estado:** tarefa, providências, afazeres (todos com responsável), histórico, anexos, links, available_users (para atribuição)

**Funcionalidades:**
- Editar: status, responsável, datas, links, providências
- Gerenciar afazeres: criar, reordenar, toggle concluído, editar observação, mudar responsável
- Upload de anexo via `DocumentPicker` → `POST /upload_attachment.php`
- Download de anexo via URL GCS assinada
- Histórico de status com datas

---

### `ProjectDetailsScreen`
A maior tela da aplicação (~97KB).

**Abas (tabs):**
1. **Visão Geral** — dados do projeto, orçamento, NUP/OS
2. **Tarefas** — lista com status_color e criação inline
3. **Equipe** — membros com status, adicionar/remover
4. **Custos** — lista de custos, adicionar, aprovar/reprovar
5. **Anexos** — upload e download de arquivos do projeto
6. **Links** — links externos
7. **Notas** — comentários da equipe
8. **Gantt** — visualização de Gantt

---

### `CreateTaskScreen`
**Props:** `user`, `demanda_id`, `demanda_descricao`

**Campos:** descrição, responsável (dropdown de usuários ou "distribuir"), data início, prazo

**Submissão:** `POST /task_actions.php` com `action=create_task`

---

### `CreateProjectScreen`
**Props:** `user`

**Campos:** descrição, resumo, divisão, tema, data_inicio, prazo, orçamento, NUP, OS

**Funcionalidades:**
- Picker de divisão (lista do BD)
- Picker de tema
- DatePicker nativo
- Upload de múltiplos anexos
- Upload de links
- **Submissão:** `POST /create_project.php` (multipart/form-data)

---

### `CreateDemandScreen`
**Props:** `user`

**Campos:** descrição, usuário destinatário, prioridade

**Funcionalidades:**
- Link editor (adicionar/remover links)
- Upload de múltiplos anexos
- **Submissão:** `POST /create_demand.php`

---

### `DemandDetailsScreen`
Demanda rápida (`tarefarapida`).

**Funcionalidades:**
- Editar descrição, status, responsável, prioridade
- Adicionar providências
- Upload/download de anexos
- Adicionar/remover links
- Conluir/cancelar/reativar demanda

---

### `DemandListScreen`
Lista de demandas rápidas dividida em abas:
- **A Fazer** — demandas atribuídas a mim
- **Por Mim** — demandas que criei para outros
- **Concluídas** — demandas fechadas

---

### `SearchResultsScreen`
**Funcionalidades:**
- Input de busca local (no topo)
- Tabs: Projetos / Tarefas / Demandas
- Suporte a busca exata com aspas
- Navega para `ProjectDetails` ou `TaskDetails` ou `DemandDetails`

---

### `NotificationsScreen`
Lista as notificações do usuário (da tabela `notificacoes`).

**Ícones por tipo:**
| tipo | ícone | cor |
|------|-------|-----|
| tarefa | clipboard | #007AFF |
| demanda | pin | #FF9500 |
| afazer | checkmark-circle | #34C759 |
| revisao | search | #AF52DE |

**Ao tocar:** navega para `TaskDetails` ou `DemandDetails` usando `referencia_id`.

---

### `CostApprovalScreen`
Listagem de custos pendentes de aprovação.

**Funcionalidades:**
- Filtro por projeto
- Modal de aprovação com campo de observação
- Chama `project_actions.php` com `action=approve_cost` ou `reject_cost`

---

### Settings Screens (Admin Only)

| Tela | API Endpoint | Funcionalidades |
|------|-------------|-----------------|
| `ConstantsScreen` | `settings/constants.php` | Edita `constantes`: nomenclaturas, a_vencer, niveis, SGF |
| `StructuresScreen` | `settings/structures.php` | CRUD hierarquia (N1-N4): divisão, coord, diretoria, estrutura_4 |
| `UsersScreen` | `settings/users.php` | CRUD usuários + sync master DB |
| `ThemesScreen` | `settings/themes.php` | CRUD temas de projeto |
| `CostCategoriesScreen` | `settings/cost_categories.php` | CRUD categorias + alçadas por cargo |
| `CostCentersScreen` | `settings/cost_centers.php` | CRUD centros de custo |

---

## Serviço de Notificações (NotificationService.js)

### `registerForPushNotifications(userId, cliente)`
- Verifica se é dispositivo físico (`Device.isDevice`)
- Solicita permissão com `Notifications.requestPermissionsAsync()`
- Obtém token Expo Push com `getExpoPushTokenAsync({ projectId })`
- Envia token para `POST /register_push_token.php`
- Configura canal Android (`setNotificationChannelAsync`)

### `setupNotificationHandler(navigationRef)`
- Chama `Notifications.setNotificationHandler` → sempre mostra alert no foreground
- Registra `addNotificationResponseReceivedListener` → ao tocar na notificação, chama `handleNotificationNavigation`
- Retorna cleanup function (para `useEffect`)

### `handleNotificationNavigation(data, navigationRef)`
- Lê `data.tipo` e `data.referencia_id` do payload
- Navega adequadamente via `navigationRef.current.navigate()`

---

## Configuração Global (config.js)

```js
export const API_URL = "http://157.245.10.199/webapp/api";
```

Todos os `fetch` usam `${API_URL}/endpoint.php`.

### Ambientes
| Ambiente | URL |
|----------|-----|
| Produção | `http://157.245.10.199/webapp/api` |
| Dev Local (LAN) | `http://192.168.0.100/antigravity/webapp/api` |
| Emulador Android | `http://10.0.2.2/antigravity/webapp/api` |

---

## Dependências do Package.json

```json
{
  "expo": "~54.0.32",
  "react": "18.3.1",
  "react-native": "0.81.5",
  "@react-navigation/native": "^7.1.6",
  "@react-navigation/native-stack": "^7.3.10",
  "expo-document-picker": "~14.0.8",
  "expo-file-system": "~19.0.21",
  "expo-print": "~14.0.3",
  "expo-sharing": "~13.0.2",
  "expo-notifications": "(última compatível)",
  "expo-device": "(última compatível)",
  "expo-constants": "(última compatível)",
  "react-native-safe-area-context": "5.4.0",
  "react-native-svg": "15.12.1",
  "react-native-view-shot": "4.0.3",
  "@expo/vector-icons": "^14.0.4",
  "date-fns": "^4.1.0"
}
```
