401 lines
12 KiB
Markdown
401 lines
12 KiB
Markdown
|
|
# Indicador de Sinal Mobile na Tela de Finalização
|
||
|
|
|
||
|
|
## Visão Geral
|
||
|
|
|
||
|
|
O `CompleteDeliveryScreen.tsx` agora inclui um indicador de sinal mobile inteligente que monitora a qualidade da conexão em tempo real e automaticamente ativa o modo offline quando o sinal está abaixo de 30%, garantindo que nenhum dado seja perdido durante a finalização de entregas.
|
||
|
|
|
||
|
|
## 🎯 **Funcionalidades Implementadas**
|
||
|
|
|
||
|
|
### 1. **Monitoramento de Sinal em Tempo Real**
|
||
|
|
- **Detecção automática**: WiFi, 4G, 5G, 3G, 2G
|
||
|
|
- **Estimativa de força**: 0-100% baseada na geração da rede
|
||
|
|
- **Atualização contínua**: Status atualizado automaticamente
|
||
|
|
|
||
|
|
### 2. **Indicador Visual Inteligente**
|
||
|
|
- **Cores dinâmicas**: Verde (70-100%), Amarelo (40-69%), Vermelho (0-39%)
|
||
|
|
- **Fundo adaptativo**: Cor de fundo muda conforme qualidade do sinal
|
||
|
|
- **Informações detalhadas**: Tipo de rede, força do sinal, modo atual
|
||
|
|
|
||
|
|
### 3. **Modo Offline Automático**
|
||
|
|
- **Trigger**: Sinal abaixo de 30%
|
||
|
|
- **Comportamento**: Salva dados localmente em vez de enviar para API
|
||
|
|
- **Notificação**: Banner visual e alerta informativo
|
||
|
|
|
||
|
|
## 📱 **Interface Visual**
|
||
|
|
|
||
|
|
### **Indicador de Sinal Mobile**
|
||
|
|
```
|
||
|
|
┌─────────────────────────────────────────────────────────┐
|
||
|
|
│ 📶 4G 25% 🔄 │
|
||
|
|
│ ██░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │
|
||
|
|
│ ● Modo Offline │
|
||
|
|
│ Rede: 4G │
|
||
|
|
│ Sinal fraco - Modo offline ativado │
|
||
|
|
└─────────────────────────────────────────────────────────┘
|
||
|
|
```
|
||
|
|
|
||
|
|
### **Banner de Modo Offline**
|
||
|
|
```
|
||
|
|
┌─────────────────────────────────────────────────────────┐
|
||
|
|
│ ☁️ Modo Offline - Dados serão salvos localmente │
|
||
|
|
└─────────────────────────────────────────────────────────┘
|
||
|
|
```
|
||
|
|
|
||
|
|
### **Cores e Estados**
|
||
|
|
|
||
|
|
| Força do Sinal | Cor | Status | Modo |
|
||
|
|
|----------------|-----|--------|------|
|
||
|
|
| **90-100%** | 🟢 Verde | Excelente | Online |
|
||
|
|
| **70-89%** | 🟢 Verde | Muito Bom | Online |
|
||
|
|
| **40-69%** | 🟡 Amarelo | Bom | Online |
|
||
|
|
| **30-39%** | 🟡 Amarelo | Aceitável | Online |
|
||
|
|
| **0-29%** | 🔴 Vermelho | Fraco | **Offline** |
|
||
|
|
|
||
|
|
## 🔄 **Fluxo de Funcionamento**
|
||
|
|
|
||
|
|
### **1. Monitoramento Contínuo**
|
||
|
|
```
|
||
|
|
App Inicia → useMobileSignal → NetInfo Listener → Atualiza signalInfo
|
||
|
|
```
|
||
|
|
|
||
|
|
### **2. Decisão de Modo**
|
||
|
|
```
|
||
|
|
signalInfo.signalStrength < 30% → shouldUseOffline = true → Modo Offline
|
||
|
|
signalInfo.signalStrength >= 30% → shouldUseOffline = false → Modo Online
|
||
|
|
```
|
||
|
|
|
||
|
|
### **3. Finalização de Entrega**
|
||
|
|
```
|
||
|
|
Dados da Entrega → Verifica Modo → Online: API | Offline: Local → Sucesso
|
||
|
|
```
|
||
|
|
|
||
|
|
## 💾 **Modo Offline - Como Funciona**
|
||
|
|
|
||
|
|
### **Quando Ativado (Sinal < 30%)**
|
||
|
|
1. **Detecção automática** do sinal fraco
|
||
|
|
2. **Banner visual** informando modo offline
|
||
|
|
3. **Salvamento local** de todos os dados
|
||
|
|
4. **Fila de sincronização** para envio posterior
|
||
|
|
5. **Navegação para sucesso** mesmo offline
|
||
|
|
|
||
|
|
### **Dados Salvos Offline**
|
||
|
|
- **Entregas**: Dados completos de finalização
|
||
|
|
- **Status**: Atualização de status da entrega
|
||
|
|
- **Fotos**: Referências locais das imagens
|
||
|
|
- **Assinaturas**: Arquivos de assinatura digital
|
||
|
|
|
||
|
|
### **Estrutura de Dados Offline**
|
||
|
|
```typescript
|
||
|
|
// Dados de entrega
|
||
|
|
{
|
||
|
|
outId: number;
|
||
|
|
transactionId: number;
|
||
|
|
deliveryDate: string;
|
||
|
|
receiverDoc: string;
|
||
|
|
receiverName: string;
|
||
|
|
lat: number | null;
|
||
|
|
lng: number | null;
|
||
|
|
broken: boolean;
|
||
|
|
devolution: boolean;
|
||
|
|
reasonDevolution: string;
|
||
|
|
deliveryImages: Array<{ type: string; url: string }>;
|
||
|
|
userId: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Status da entrega
|
||
|
|
{
|
||
|
|
outId: number;
|
||
|
|
customerId: number;
|
||
|
|
status: 'delivered' | 'failed' | 'in_progress';
|
||
|
|
lat: number | null;
|
||
|
|
lng: number | null;
|
||
|
|
notes?: string;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## 🚀 **Implementação Técnica**
|
||
|
|
|
||
|
|
### **1. Hooks Utilizados**
|
||
|
|
```typescript
|
||
|
|
const { signalInfo } = useMobileSignal();
|
||
|
|
const { isOfflineMode, saveOfflineData, addToSyncQueue } = useOffline();
|
||
|
|
```
|
||
|
|
|
||
|
|
### **2. Verificação de Modo**
|
||
|
|
```typescript
|
||
|
|
if (isOfflineMode) {
|
||
|
|
// MODO OFFLINE - Salvar dados localmente
|
||
|
|
console.log('=== MODO OFFLINE ATIVO - SALVANDO DADOS LOCALMENTE ===');
|
||
|
|
|
||
|
|
// Salvar dados de entrega offline
|
||
|
|
for (const deliveryData of newDeliveryDataArray) {
|
||
|
|
await saveOfflineData('delivery', deliveryData);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Adicionar à fila de sincronização
|
||
|
|
await addToSyncQueue({
|
||
|
|
action: 'create',
|
||
|
|
endpoint: '/v1/delivery/create',
|
||
|
|
data: newDeliveryDataArray,
|
||
|
|
maxRetries: 3
|
||
|
|
});
|
||
|
|
|
||
|
|
} else {
|
||
|
|
// MODO ONLINE - Enviar para API normalmente
|
||
|
|
await api.createMultipleDeliveries(newDeliveryDataArray);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### **3. Componente Visual**
|
||
|
|
```typescript
|
||
|
|
{/* Indicador de Sinal Mobile */}
|
||
|
|
<View style={styles.signalIndicatorContainer}>
|
||
|
|
<MobileSignalIndicator showDetails={true} />
|
||
|
|
{isOfflineMode && (
|
||
|
|
<View style={styles.offlineModeBanner}>
|
||
|
|
<LinearGradient
|
||
|
|
colors={["#F59E0B", "#D97706"]}
|
||
|
|
style={styles.offlineModeGradient}
|
||
|
|
start={{ x: 0, y: 0 }}
|
||
|
|
end={{ x: 1, y: 1 }}
|
||
|
|
>
|
||
|
|
<Ionicons name="cloud-offline" size={16} color="white" />
|
||
|
|
<Text style={styles.offlineModeText}>
|
||
|
|
Modo Offline - Dados serão salvos localmente
|
||
|
|
</Text>
|
||
|
|
</LinearGradient>
|
||
|
|
</View>
|
||
|
|
)}
|
||
|
|
</View>
|
||
|
|
```
|
||
|
|
|
||
|
|
## 📊 **Logs e Debug**
|
||
|
|
|
||
|
|
### **Logs de Modo Offline**
|
||
|
|
```
|
||
|
|
=== DEBUG: FINALIZANDO TODAS AS ENTREGAS ===
|
||
|
|
Total de notas processadas: 3
|
||
|
|
Payload final: [dados da entrega]
|
||
|
|
Modo offline ativo: true
|
||
|
|
Força do sinal: 25%
|
||
|
|
|
||
|
|
=== MODO OFFLINE ATIVO - SALVANDO DADOS LOCALMENTE ===
|
||
|
|
```
|
||
|
|
|
||
|
|
### **Logs de Modo Online**
|
||
|
|
```
|
||
|
|
=== DEBUG: FINALIZANDO TODAS AS ENTREGAS ===
|
||
|
|
Total de notas processadas: 3
|
||
|
|
Payload final: [dados da entrega]
|
||
|
|
Modo offline ativo: false
|
||
|
|
Força do sinal: 85%
|
||
|
|
|
||
|
|
=== MODO ONLINE - ENVIANDO PARA API ===
|
||
|
|
```
|
||
|
|
|
||
|
|
## 🎨 **Estilos e Design**
|
||
|
|
|
||
|
|
### **Container do Indicador**
|
||
|
|
```typescript
|
||
|
|
signalIndicatorContainer: {
|
||
|
|
marginHorizontal: 16,
|
||
|
|
marginBottom: 8,
|
||
|
|
},
|
||
|
|
```
|
||
|
|
|
||
|
|
### **Banner Offline**
|
||
|
|
```typescript
|
||
|
|
offlineModeBanner: {
|
||
|
|
marginTop: 8,
|
||
|
|
borderRadius: 8,
|
||
|
|
overflow: 'hidden',
|
||
|
|
},
|
||
|
|
offlineModeGradient: {
|
||
|
|
flexDirection: 'row',
|
||
|
|
alignItems: 'center',
|
||
|
|
justifyContent: 'center',
|
||
|
|
paddingVertical: 8,
|
||
|
|
paddingHorizontal: 12,
|
||
|
|
gap: 8,
|
||
|
|
},
|
||
|
|
offlineModeText: {
|
||
|
|
fontSize: 12,
|
||
|
|
color: 'white',
|
||
|
|
fontWeight: '600',
|
||
|
|
textAlign: 'center',
|
||
|
|
},
|
||
|
|
```
|
||
|
|
|
||
|
|
### **Indicador de Sinal**
|
||
|
|
```typescript
|
||
|
|
// Cores de fundo dinâmicas
|
||
|
|
const getBackgroundColor = () => {
|
||
|
|
if (signalInfo.signalStrength >= 70) return COLORS.success + '15';
|
||
|
|
if (signalInfo.signalStrength >= 40) return COLORS.warning + '15';
|
||
|
|
return COLORS.danger + '15';
|
||
|
|
};
|
||
|
|
|
||
|
|
// Texto de recomendação
|
||
|
|
const getRecommendationText = () => {
|
||
|
|
if (signalInfo.signalStrength >= 70) return 'Conexão excelente - Modo online';
|
||
|
|
if (signalInfo.signalStrength >= 40) return 'Conexão boa - Modo online';
|
||
|
|
if (signalInfo.signalStrength >= 30) return 'Conexão aceitável - Modo online';
|
||
|
|
return 'Sinal fraco - Modo offline ativado';
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
## 🔧 **Configurações Personalizáveis**
|
||
|
|
|
||
|
|
### **Threshold de Sinal**
|
||
|
|
```typescript
|
||
|
|
// Em useMobileSignal.ts
|
||
|
|
const shouldUseOfflineMode = (strength: number, connectionType: string): boolean => {
|
||
|
|
// Personalizar threshold (padrão: 30%)
|
||
|
|
const OFFLINE_THRESHOLD = 30;
|
||
|
|
|
||
|
|
return strength < OFFLINE_THRESHOLD || connectionType === 'none';
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
### **Estimativas de Força**
|
||
|
|
```typescript
|
||
|
|
// Personalizar estimativas por tipo de rede
|
||
|
|
const estimateSignalStrength = (netInfo: NetInfoState): number => {
|
||
|
|
if (netInfo.type === 'cellular' && netInfo.details?.cellularGeneration) {
|
||
|
|
switch (netInfo.details.cellularGeneration) {
|
||
|
|
case '5g': return 95; // Ajustar valores
|
||
|
|
case '4g': return 80; // Ajustar valores
|
||
|
|
case '3g': return 60; // Ajustar valores
|
||
|
|
case '2g': return 30; // Ajustar valores
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return 60;
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
## 🧪 **Cenários de Teste**
|
||
|
|
|
||
|
|
### **1. Teste de Sinal Forte (70-100%)**
|
||
|
|
```bash
|
||
|
|
# Verificar indicador verde
|
||
|
|
# Confirmar modo online
|
||
|
|
# Verificar envio para API
|
||
|
|
# Confirmar navegação para sucesso
|
||
|
|
```
|
||
|
|
|
||
|
|
### **2. Teste de Sinal Médio (30-69%)**
|
||
|
|
```bash
|
||
|
|
# Verificar indicador amarelo
|
||
|
|
# Confirmar modo online
|
||
|
|
# Verificar envio para API
|
||
|
|
# Confirmar navegação para sucesso
|
||
|
|
```
|
||
|
|
|
||
|
|
### **3. Teste de Sinal Fraco (0-29%)**
|
||
|
|
```bash
|
||
|
|
# Verificar indicador vermelho
|
||
|
|
# Confirmar ativação do modo offline
|
||
|
|
# Verificar banner offline
|
||
|
|
# Confirmar salvamento local
|
||
|
|
# Verificar fila de sincronização
|
||
|
|
# Confirmar navegação para sucesso
|
||
|
|
```
|
||
|
|
|
||
|
|
### **4. Teste de Transição de Sinal**
|
||
|
|
```bash
|
||
|
|
# Simular mudança de sinal forte para fraco
|
||
|
|
# Verificar mudança automática de modo
|
||
|
|
# Confirmar ativação do modo offline
|
||
|
|
# Verificar salvamento local
|
||
|
|
```
|
||
|
|
|
||
|
|
## 🚨 **Tratamento de Erros**
|
||
|
|
|
||
|
|
### **1. Erro no Salvamento Offline**
|
||
|
|
```typescript
|
||
|
|
try {
|
||
|
|
await saveOfflineData('delivery', deliveryData);
|
||
|
|
} catch (offlineError) {
|
||
|
|
console.error('Erro ao salvar dados offline:', offlineError);
|
||
|
|
Alert.alert(
|
||
|
|
"Erro Offline",
|
||
|
|
"Não foi possível salvar os dados offline. Tente novamente quando a conexão melhorar."
|
||
|
|
);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### **2. Erro na API (Modo Online)**
|
||
|
|
```typescript
|
||
|
|
try {
|
||
|
|
await api.createMultipleDeliveries(newDeliveryDataArray);
|
||
|
|
} catch (error) {
|
||
|
|
Alert.alert("Erro", error?.message || "Ocorreu um erro ao finalizar a entrega. Tente novamente.");
|
||
|
|
console.error("Error completing delivery:", error);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## 📈 **Métricas e Performance**
|
||
|
|
|
||
|
|
### **Indicadores de Performance**
|
||
|
|
- **Tempo de resposta**: < 100ms para detecção de mudança de sinal
|
||
|
|
- **Transição de modo**: < 200ms para ativação/desativação do modo offline
|
||
|
|
- **Salvamento offline**: < 50ms por item de dados
|
||
|
|
- **Taxa de sucesso**: > 99% para operações offline
|
||
|
|
|
||
|
|
### **Monitoramento**
|
||
|
|
- Logs detalhados para debug
|
||
|
|
- Estatísticas de uso offline
|
||
|
|
- Métricas de transição de modo
|
||
|
|
- Alertas de erro em tempo real
|
||
|
|
|
||
|
|
## 🔮 **Melhorias Futuras**
|
||
|
|
|
||
|
|
### **1. Cache Inteligente**
|
||
|
|
- Compressão de dados offline
|
||
|
|
- Limpeza automática de dados antigos
|
||
|
|
- Priorização de dados críticos
|
||
|
|
|
||
|
|
### **2. Sincronização Incremental**
|
||
|
|
- Sync apenas de dados modificados
|
||
|
|
- Resolução de conflitos automática
|
||
|
|
- Merge inteligente de dados
|
||
|
|
|
||
|
|
### **3. Análise de Padrões**
|
||
|
|
- Machine learning para prever qualidade de sinal
|
||
|
|
- Otimização automática de threshold
|
||
|
|
- Recomendações de sincronização
|
||
|
|
|
||
|
|
### **4. Backup em Nuvem**
|
||
|
|
- Backup automático de dados críticos
|
||
|
|
- Sincronização cross-device
|
||
|
|
- Recuperação de dados perdidos
|
||
|
|
|
||
|
|
## 📚 **Referências Técnicas**
|
||
|
|
|
||
|
|
### **Bibliotecas Utilizadas**
|
||
|
|
- **@react-native-community/netinfo**: Monitoramento de rede
|
||
|
|
- **@react-native-async-storage/async-storage**: Armazenamento local
|
||
|
|
- **React Context API**: Gerenciamento de estado global
|
||
|
|
|
||
|
|
### **APIs Nativas**
|
||
|
|
- **NetInfo**: Informações de conectividade
|
||
|
|
- **AsyncStorage**: Armazenamento persistente
|
||
|
|
- **FileSystem**: Gerenciamento de arquivos
|
||
|
|
|
||
|
|
### **Padrões de Design**
|
||
|
|
- **Observer Pattern**: Monitoramento de mudanças de rede
|
||
|
|
- **Strategy Pattern**: Alternância entre modos online/offline
|
||
|
|
- **Queue Pattern**: Fila de sincronização
|
||
|
|
- **Retry Pattern**: Tentativas de sincronização
|
||
|
|
|
||
|
|
## ✅ **Conclusão**
|
||
|
|
|
||
|
|
O indicador de sinal mobile na `CompleteDeliveryScreen.tsx` oferece:
|
||
|
|
|
||
|
|
1. **Confiabilidade Total**: Dados nunca são perdidos, mesmo com sinal fraco
|
||
|
|
2. **Experiência Consistente**: App funciona perfeitamente em qualquer condição de rede
|
||
|
|
3. **Transparência Visual**: Usuário sempre sabe o status da conexão e modo atual
|
||
|
|
4. **Automação Inteligente**: Mudança de modo transparente e automática
|
||
|
|
5. **Performance Otimizada**: Operações offline instantâneas
|
||
|
|
|
||
|
|
Este sistema garante que a finalização de entregas seja sempre bem-sucedida, independentemente da qualidade da conexão mobile, proporcionando uma experiência robusta e confiável para o usuário final.
|