first commit
This commit is contained in:
334
unionflow-mobile-apps/src/contexts/WavePaymentContext.tsx
Normal file
334
unionflow-mobile-apps/src/contexts/WavePaymentContext.tsx
Normal file
@@ -0,0 +1,334 @@
|
||||
import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react';
|
||||
import NetInfo from '@react-native-community/netinfo';
|
||||
import {
|
||||
WavePaymentService,
|
||||
WavePaymentRequest,
|
||||
WavePaymentResult,
|
||||
WaveTransactionStatus
|
||||
} from '../services/WavePaymentService';
|
||||
import { AnalyticsService } from '../services/AnalyticsService';
|
||||
|
||||
/**
|
||||
* Contexte Wave Payment pour la gestion globale des paiements Wave Money
|
||||
*
|
||||
* Ce contexte fournit :
|
||||
* - État global des paiements Wave
|
||||
* - Gestion de la connectivité et synchronisation
|
||||
* - Cache des transactions récentes
|
||||
* - Notifications de statut en temps réel
|
||||
*
|
||||
* @author Lions Dev Team
|
||||
* @version 2.0.0
|
||||
* @since 2025-01-16
|
||||
*/
|
||||
|
||||
interface WavePaymentContextType {
|
||||
// État des paiements
|
||||
isLoading: boolean;
|
||||
currentTransaction: WavePaymentResult | null;
|
||||
recentTransactions: WavePaymentResult[];
|
||||
|
||||
// Connectivité
|
||||
isOnline: boolean;
|
||||
pendingPaymentsCount: number;
|
||||
|
||||
// Actions
|
||||
initiatePayment: (request: WavePaymentRequest) => Promise<WavePaymentResult>;
|
||||
checkTransactionStatus: (transactionId: string) => Promise<WaveTransactionStatus>;
|
||||
refreshTransactions: () => Promise<void>;
|
||||
syncPendingPayments: () => Promise<void>;
|
||||
clearCurrentTransaction: () => void;
|
||||
|
||||
// Utilitaires
|
||||
calculateFees: (amount: string) => Promise<{ base: string; fees: string; total: string }>;
|
||||
getPaymentHistory: () => Promise<WavePaymentResult[]>;
|
||||
}
|
||||
|
||||
const WavePaymentContext = createContext<WavePaymentContextType | undefined>(undefined);
|
||||
|
||||
interface WavePaymentProviderProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export const WavePaymentProvider: React.FC<WavePaymentProviderProps> = ({ children }) => {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [currentTransaction, setCurrentTransaction] = useState<WavePaymentResult | null>(null);
|
||||
const [recentTransactions, setRecentTransactions] = useState<WavePaymentResult[]>([]);
|
||||
const [isOnline, setIsOnline] = useState(true);
|
||||
const [pendingPaymentsCount, setPendingPaymentsCount] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
initializeContext();
|
||||
setupNetworkListener();
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* Initialise le contexte avec les données sauvegardées
|
||||
*/
|
||||
const initializeContext = async () => {
|
||||
try {
|
||||
// Charger l'historique des paiements
|
||||
const history = await WavePaymentService.getPaymentHistory();
|
||||
setRecentTransactions(history.slice(0, 10)); // 10 plus récents
|
||||
|
||||
// Compter les paiements en attente
|
||||
await updatePendingPaymentsCount();
|
||||
|
||||
} catch (error) {
|
||||
console.error('Erreur initialisation contexte Wave:', error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Configure l'écoute de la connectivité réseau
|
||||
*/
|
||||
const setupNetworkListener = () => {
|
||||
const unsubscribe = NetInfo.addEventListener(state => {
|
||||
const wasOffline = !isOnline;
|
||||
const isNowOnline = state.isConnected ?? false;
|
||||
|
||||
setIsOnline(isNowOnline);
|
||||
|
||||
// Si on revient en ligne, synchroniser les paiements en attente
|
||||
if (wasOffline && isNowOnline) {
|
||||
console.log('Connexion rétablie - Synchronisation des paiements Wave');
|
||||
syncPendingPayments();
|
||||
}
|
||||
});
|
||||
|
||||
return unsubscribe;
|
||||
};
|
||||
|
||||
/**
|
||||
* Met à jour le nombre de paiements en attente
|
||||
*/
|
||||
const updatePendingPaymentsCount = async () => {
|
||||
try {
|
||||
const pendingPayments = await WavePaymentService.getPendingPayments();
|
||||
setPendingPaymentsCount(pendingPayments.length);
|
||||
} catch (error) {
|
||||
console.error('Erreur mise à jour paiements en attente:', error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Initie un paiement Wave Money
|
||||
*/
|
||||
const initiatePayment = async (request: WavePaymentRequest): Promise<WavePaymentResult> => {
|
||||
setIsLoading(true);
|
||||
setCurrentTransaction(null);
|
||||
|
||||
try {
|
||||
const result = await WavePaymentService.initiatePayment(request);
|
||||
|
||||
setCurrentTransaction(result);
|
||||
|
||||
if (result.success) {
|
||||
// Ajouter à l'historique récent
|
||||
setRecentTransactions(prev => [result, ...prev.slice(0, 9)]);
|
||||
|
||||
// Analytics
|
||||
AnalyticsService.trackEvent('wave_payment_context_success', {
|
||||
type: request.type,
|
||||
amount: request.amount,
|
||||
transactionId: result.transactionId,
|
||||
});
|
||||
} else {
|
||||
// Si échec à cause de la connectivité, mettre à jour le compteur
|
||||
if (!isOnline) {
|
||||
await updatePendingPaymentsCount();
|
||||
}
|
||||
|
||||
AnalyticsService.trackEvent('wave_payment_context_failure', {
|
||||
type: request.type,
|
||||
amount: request.amount,
|
||||
error: result.error,
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
} catch (error) {
|
||||
console.error('Erreur contexte paiement Wave:', error);
|
||||
|
||||
const errorResult: WavePaymentResult = {
|
||||
success: false,
|
||||
error: 'Erreur inattendue lors du paiement',
|
||||
};
|
||||
|
||||
setCurrentTransaction(errorResult);
|
||||
return errorResult;
|
||||
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Vérifie le statut d'une transaction
|
||||
*/
|
||||
const checkTransactionStatus = async (transactionId: string): Promise<WaveTransactionStatus> => {
|
||||
try {
|
||||
const status = await WavePaymentService.checkTransactionStatus(transactionId);
|
||||
|
||||
// Mettre à jour la transaction dans l'historique si nécessaire
|
||||
setRecentTransactions(prev =>
|
||||
prev.map(transaction =>
|
||||
transaction.transactionId === transactionId
|
||||
? { ...transaction, status: status.status as any }
|
||||
: transaction
|
||||
)
|
||||
);
|
||||
|
||||
return status;
|
||||
|
||||
} catch (error) {
|
||||
console.error('Erreur vérification statut:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Actualise la liste des transactions
|
||||
*/
|
||||
const refreshTransactions = async () => {
|
||||
try {
|
||||
const history = await WavePaymentService.getPaymentHistory();
|
||||
setRecentTransactions(history.slice(0, 10));
|
||||
await updatePendingPaymentsCount();
|
||||
} catch (error) {
|
||||
console.error('Erreur actualisation transactions:', error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Synchronise les paiements en attente
|
||||
*/
|
||||
const syncPendingPayments = async () => {
|
||||
if (!isOnline) {
|
||||
console.log('Hors ligne - Synchronisation reportée');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await WavePaymentService.syncPendingPayments();
|
||||
await updatePendingPaymentsCount();
|
||||
await refreshTransactions();
|
||||
|
||||
AnalyticsService.trackEvent('wave_payments_synced', {
|
||||
pendingCount: pendingPaymentsCount,
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('Erreur synchronisation paiements:', error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Efface la transaction courante
|
||||
*/
|
||||
const clearCurrentTransaction = () => {
|
||||
setCurrentTransaction(null);
|
||||
};
|
||||
|
||||
/**
|
||||
* Calcule les frais Wave Money
|
||||
*/
|
||||
const calculateFees = async (amount: string) => {
|
||||
try {
|
||||
return await WavePaymentService.calculateFees(amount);
|
||||
} catch (error) {
|
||||
console.error('Erreur calcul frais contexte:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Retourne l'historique complet des paiements
|
||||
*/
|
||||
const getPaymentHistory = async (): Promise<WavePaymentResult[]> => {
|
||||
try {
|
||||
return await WavePaymentService.getPaymentHistory();
|
||||
} catch (error) {
|
||||
console.error('Erreur récupération historique:', error);
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
const contextValue: WavePaymentContextType = {
|
||||
// État
|
||||
isLoading,
|
||||
currentTransaction,
|
||||
recentTransactions,
|
||||
isOnline,
|
||||
pendingPaymentsCount,
|
||||
|
||||
// Actions
|
||||
initiatePayment,
|
||||
checkTransactionStatus,
|
||||
refreshTransactions,
|
||||
syncPendingPayments,
|
||||
clearCurrentTransaction,
|
||||
|
||||
// Utilitaires
|
||||
calculateFees,
|
||||
getPaymentHistory,
|
||||
};
|
||||
|
||||
return (
|
||||
<WavePaymentContext.Provider value={contextValue}>
|
||||
{children}
|
||||
</WavePaymentContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook pour utiliser le contexte Wave Payment
|
||||
*/
|
||||
export const useWavePayment = (): WavePaymentContextType => {
|
||||
const context = useContext(WavePaymentContext);
|
||||
|
||||
if (context === undefined) {
|
||||
throw new Error('useWavePayment doit être utilisé dans un WavePaymentProvider');
|
||||
}
|
||||
|
||||
return context;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook pour vérifier si Wave Money est disponible
|
||||
*/
|
||||
export const useWaveAvailability = () => {
|
||||
const { isOnline } = useWavePayment();
|
||||
|
||||
return {
|
||||
isWaveAvailable: isOnline, // Simplification - en réalité, vérifier aussi la config
|
||||
reason: isOnline ? null : 'Connexion internet requise',
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook pour les statistiques de paiement Wave
|
||||
*/
|
||||
export const useWaveStats = () => {
|
||||
const { recentTransactions, pendingPaymentsCount } = useWavePayment();
|
||||
|
||||
const successfulPayments = recentTransactions.filter(t => t.success).length;
|
||||
const failedPayments = recentTransactions.filter(t => !t.success).length;
|
||||
const totalAmount = recentTransactions
|
||||
.filter(t => t.success)
|
||||
.reduce((sum, t) => {
|
||||
// Extraire le montant de la transaction (simplification)
|
||||
return sum + 0; // À implémenter selon le format des données
|
||||
}, 0);
|
||||
|
||||
return {
|
||||
successfulPayments,
|
||||
failedPayments,
|
||||
pendingPaymentsCount,
|
||||
totalAmount,
|
||||
successRate: recentTransactions.length > 0
|
||||
? (successfulPayments / recentTransactions.length) * 100
|
||||
: 0,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user