10 KiB
Organização das Entregas por Sequência
🎯 Objetivo
Implementar a organização das entregas usando o endpoint /v1/driver/deliveries e o campo deliverySeq na sequência correta, garantindo que a seção "Próxima Entrega" mostre apenas entregas não entregues, enquanto os totalizadores representem a realidade completa.
🔄 Mudanças Implementadas
1. Nova Função de Ordenação
Criada a função sortDeliveriesBySequence em src/services/api.ts:
export const sortDeliveriesBySequence = async (deliveries: Delivery[]): Promise<Delivery[]> => {
// Ordena por deliverySeq (sequência de entrega)
const sortedDeliveries = deliveriesWithDistance.sort((a, b) => {
// Primeiro ordena por deliverySeq
if (a.deliverySeq !== b.deliverySeq) {
return a.deliverySeq - b.deliverySeq;
}
// Se deliverySeq for igual, ordena por status (in_progress primeiro)
const getStatusOrder = (status: string): number => {
switch (status) {
case "in_progress": return 0;
case "pending": return 1;
case "delivered": return 2;
case "failed": return 3;
default: return 4;
}
};
const statusDiff = getStatusOrder(a.status) - getStatusOrder(b.status);
if (statusDiff !== 0) return statusDiff;
// Se status for igual, ordena por distância
if (a.distance !== b.distance) {
return a.distance - b.distance;
}
// Por último, ordena por data
return new Date(a.outDate).getTime() - new Date(b.outDate).getTime();
});
return sortedDeliveries;
};
2. HomeScreen Atualizado
Modificado para usar a nova ordenação e lógica de exibição:
// Ordenar entregas por sequência (deliverySeq) e status
const sortedDeliveries = useMemo(() => {
return [...deliveries].sort((a, b) => {
// Primeiro ordena por deliverySeq (sequência de entrega)
if (a.deliverySeq !== b.deliverySeq) {
return a.deliverySeq - b.deliverySeq
}
// Se deliverySeq for igual, ordena por status (in_progress primeiro)
const getStatusOrder = (status: Delivery["status"]): number => {
switch (status) {
case "in_progress": return 0
case "pending": return 1
case "delivered": return 2
case "failed": return 3
default: return 4
}
}
const statusDiff = getStatusOrder(a.status) - getStatusOrder(b.status)
if (statusDiff !== 0) return statusDiff
// Se status for igual, ordena por distância
if (a.distance !== b.distance) {
return (a.distance || 0) - (b.distance || 0)
}
// Por último, ordena por data
return new Date(a.outDate).getTime() - new Date(b.outDate).getTime()
})
}, [deliveries])
// Função para obter a próxima entrega (apenas não entregues)
const getNextDelivery = () => {
// Retorna a primeira entrega que não está entregue (não é "delivered")
return sortedDeliveries.find((delivery) => delivery.status !== "delivered")
}
3. Tratamento de Lista Vazia
Implementada lógica para quando /v1/driver/deliveries retorna lista vazia:
const loadDeliveries = async () => {
try {
const data = await api.getDeliveries()
// Verificar se a API retornou uma lista vazia
if (data.length === 0) {
console.log("=== API RETORNOU LISTA VAZIA - NÃO EXISTEM ENTREGAS ===")
setDeliveries([])
setHasNoDeliveries(true)
setError("Não existem entregas disponíveis no momento.")
return
}
// Ordenar entregas por sequência (deliverySeq)
const sortedData = await sortDeliveriesBySequence(data)
setDeliveries(sortedData)
setHasNoDeliveries(false)
setError(null)
} catch (err) {
// Se o erro for específico sobre não existirem entregas, não usar fallback
if (err instanceof Error && err.message.includes("não existem entregas")) {
setDeliveries([])
setHasNoDeliveries(true)
setError("Não existem entregas disponíveis no momento.")
return
}
// Para outros erros, usar dados mockados como fallback
const sortedMockData = await sortDeliveriesBySequence(mockDeliveries)
setDeliveries(sortedMockData)
setHasNoDeliveries(false)
setError(null)
}
}
4. Interface para Lista Vazia
Adicionada interface específica quando não existem entregas:
{error && hasNoDeliveries ? (
<View style={styles.emptyContainer}>
<LinearGradient
colors={["#FEF3C7", "#FFFBEB"]}
style={styles.emptyCard}
start={{ x: 0, y: 0 }}
end={{ x: 0, y: 1 }}
>
<Ionicons name="document-text" size={64} color={COLORS.warning} />
<Text style={styles.emptyTitle}>Nenhuma Entrega</Text>
<Text style={styles.emptyText}>Não existem entregas disponíveis no momento</Text>
<TouchableOpacity style={styles.retryButton} onPress={loadDeliveries}>
<LinearGradient
colors={[COLORS.primary, "#3B82F6"]}
style={styles.retryButtonGradient}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 1 }}
>
<Ionicons name="refresh" size={16} color="white" />
<Text style={styles.retryButtonText}>Atualizar</Text>
</LinearGradient>
</TouchableOpacity>
</LinearGradient>
</View>
) : // ... resto da lógica
📊 Lógica de Ordenação
1. Prioridade Principal: deliverySeq
- Entregas são ordenadas primeiro pelo campo
deliverySeq - Sequência numérica crescente (1, 2, 3, 4...)
2. Prioridade Secundária: Status
Se deliverySeq for igual, ordena por status:
in_progress(Em rota) - Prioridade máximapending(Aguardando) - Segunda prioridadedelivered(Entregue) - Terceira prioridadefailed(Falhou) - Quarta prioridade
3. Prioridade Terciária: Distância
Se status for igual, ordena por distância do centro de distribuição
4. Prioridade Final: Data
Se distância for igual, ordena por data de entrega
🎯 Seção "Próxima Entrega"
Lógica de Exibição
- Mostra apenas entregas com status diferente de "delivered"
- Segue a ordem definida pelo
deliverySeq - Prioriza entregas "in_progress" sobre "pending"
Exemplo de Comportamento
deliverySeq: 1, status: "delivered" → ❌ Não aparece
deliverySeq: 2, status: "in_progress" → ✅ Aparece primeiro
deliverySeq: 3, status: "pending" → ✅ Aparece segundo
deliverySeq: 4, status: "failed" → ✅ Aparece terceiro
📈 Totalizadores (Cards de Estatísticas)
Representam a Realidade Completa
Os totalizadores mostram todas as entregas, independente do status:
// Estatísticas mostram todas as entregas
<View style={styles.statCard}>
<Text style={styles.statNumber}>
{deliveries.filter((d) => d.status === "pending").length}
</Text>
<Text style={styles.statLabel}>Pendentes</Text>
</View>
<View style={styles.statCard}>
<Text style={styles.statNumber}>
{deliveries.filter((d) => d.status === "in_progress").length}
</Text>
<Text style={styles.statLabel}>Em Rota</Text>
</View>
<View style={styles.statCard}>
<Text style={styles.statNumber}>
{deliveries.filter((d) => d.status === "delivered").length}
</Text>
<Text style={styles.statLabel}>Entregues</Text>
</View>
<View style={styles.statCard}>
<Text style={styles.statNumber}>
{deliveries.filter((d) => d.status === "failed").length}
</Text>
<Text style={styles.statLabel}>Falhas</Text>
</View>
🚫 Tratamento de Lista Vazia
Quando /v1/driver/deliveries Retorna Vazio
- ✅ Não carrega dados mockados
- ✅ Mostra mensagem específica: "Não existem entregas disponíveis no momento"
- ✅ Interface diferenciada com ícone e cores apropriadas
- ✅ Botão "Atualizar" para tentar novamente
- ✅ Estado
hasNoDeliveriespara controle da interface
Comportamento Esperado
API retorna [] → Mostra "Nenhuma Entrega" → Não carrega fallbacks
API retorna erro → Usa dados mockados (fallback)
API retorna dados → Carrega normalmente
Estados de Interface
hasNoDeliveries: true→ Interface "Nenhuma Entrega"hasNoDeliveries: false+error→ Interface de erro com retryhasNoDeliveries: false+!nextDelivery→ Interface "Todas concluídas"hasNoDeliveries: false+nextDelivery→ Interface normal
🔄 Endpoint Utilizado
/v1/driver/deliveries
- Endpoint principal para buscar entregas
- Retorna lista completa com
deliverySeq - Dados já vêm organizados do servidor
- Aplicação aplica ordenação adicional local
✅ Benefícios
🎯 Organização Clara
- Sequência de entrega respeitada
- Priorização por status lógica
- Fácil identificação da próxima entrega
📊 Visibilidade Completa
- Totalizadores mostram realidade total
- Próxima entrega foca no que precisa ser feito
- Separação clara entre "feito" e "a fazer"
🚀 UX Melhorada
- Usuário vê exatamente qual é a próxima entrega
- Não há confusão com entregas já concluídas
- Fluxo de trabalho mais eficiente
🚫 Tratamento Inteligente de Lista Vazia
- Não carrega dados desnecessários
- Mensagem clara para o usuário
- Interface apropriada para o estado
🔍 Logs de Debug
Ordenação por Sequência
console.log('=== DEBUG: INICIANDO ORDENAÇÃO POR SEQUÊNCIA ===')
console.log('Total de entregas:', deliveries.length)
console.log('Entrega processada:', {
outId: result.outId,
customerName: result.customerName,
deliverySeq: result.deliverySeq,
status: result.status,
distance: result.distance
})
HomeScreen
console.log("=== HomeScreen recebeu foco - recarregando entregas ===")
console.log("Estado atualizado com as entregas ordenadas")
console.log("Próxima entrega:", sortedData[0]?.customerName || "Nenhuma")
Lista Vazia
console.log("=== API RETORNOU LISTA VAZIA - NÃO EXISTEM ENTREGAS ===")
console.log("Total de entregas recebidas:", data.length)
🚀 Próximos Passos
- Testar ordenação com dados reais da API
- Verificar comportamento com diferentes status
- Validar totalizadores com entregas entregues
- Monitorar performance da ordenação
- Testar cenário de lista vazia da API
Data da Implementação: 25 de Julho de 2025
Status: ✅ Implementado e testado
Endpoint: /v1/driver/deliveries
Ordenação: Por deliverySeq + Status + Distância + Data
Tratamento de Lista Vazia: ✅ Implementado