152 lines
5.2 KiB
TypeScript
152 lines
5.2 KiB
TypeScript
/**
|
|
* Notification Service - Platform-aware notification management
|
|
* Uses Firebase abstraction layer for cross-platform support
|
|
*/
|
|
import { doc, FieldValue } from '../firebase';
|
|
import { WalletService } from './walletService';
|
|
import { TransactionService } from './transactionService';
|
|
import { RequestService } from './requestService';
|
|
|
|
export class NotificationService {
|
|
|
|
/**
|
|
* Mark notification as read
|
|
*/
|
|
static async markAsRead(notificationId: string): Promise<{ success: boolean; error?: string }> {
|
|
try {
|
|
const notificationRef = doc('notifications', notificationId);
|
|
await notificationRef.update({
|
|
read: true,
|
|
updatedAt: FieldValue.serverTimestamp(),
|
|
});
|
|
|
|
return { success: true };
|
|
} catch (error) {
|
|
console.error('Error marking notification as read:', error);
|
|
return {
|
|
success: false,
|
|
error: error instanceof Error ? error.message : 'Failed to mark notification as read',
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Mark all notifications as read for a user
|
|
*/
|
|
static async markAllAsRead(uid: string): Promise<{ success: boolean; error?: string }> {
|
|
try {
|
|
// This would require a batch update in a real implementation
|
|
return { success: true };
|
|
} catch (error) {
|
|
console.error('Error marking all notifications as read:', error);
|
|
return {
|
|
success: false,
|
|
error: error instanceof Error ? error.message : 'Failed to mark all notifications as read',
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Delete a notification
|
|
*/
|
|
static async deleteNotification(notificationId: string): Promise<{ success: boolean; error?: string }> {
|
|
try {
|
|
const notificationRef = doc('notifications', notificationId);
|
|
await notificationRef.delete();
|
|
return { success: true };
|
|
} catch (error) {
|
|
console.error('Error deleting notification:', error);
|
|
return {
|
|
success: false,
|
|
error: error instanceof Error ? error.message : 'Failed to delete notification',
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Accept or decline a money request and create appropriate notifications
|
|
*/
|
|
static async acceptDeclineMoneyRequest(
|
|
requestId: string,
|
|
requesteeUid: string,
|
|
requestorUid: string,
|
|
requestorName: string,
|
|
requesteeName: string,
|
|
amount: number,
|
|
action: 'accept' | 'decline'
|
|
): Promise<{ success: boolean; error?: string }> {
|
|
try {
|
|
// If accepting, handle wallet transactions
|
|
if (action === 'accept') {
|
|
// Check if requestee has sufficient balance
|
|
const requesteeWalletResult = await WalletService.getUserWallet(requesteeUid);
|
|
if (!requesteeWalletResult.success || !requesteeWalletResult.wallet) {
|
|
return { success: false, error: 'Requestee wallet not found' };
|
|
}
|
|
|
|
if (requesteeWalletResult.wallet.balance < amount) {
|
|
return { success: false, error: 'Insufficient balance to fulfill request' };
|
|
}
|
|
|
|
// Deduct amount from requestee's wallet
|
|
const newRequesteeBalance = requesteeWalletResult.wallet.balance - amount;
|
|
const deductResult = await WalletService.updateWalletBalance(requesteeUid, newRequesteeBalance);
|
|
if (!deductResult.success) {
|
|
return { success: false, error: 'Failed to deduct amount from requestee wallet' };
|
|
}
|
|
|
|
// Add amount to requestor's wallet
|
|
const requestorWalletResult = await WalletService.getUserWallet(requestorUid);
|
|
if (!requestorWalletResult.success || !requestorWalletResult.wallet) {
|
|
await WalletService.createUserWallet(requestorUid);
|
|
const newRequestorBalance = amount;
|
|
await WalletService.updateWalletBalance(requestorUid, newRequestorBalance);
|
|
} else {
|
|
const newRequestorBalance = requestorWalletResult.wallet.balance + amount;
|
|
const addResult = await WalletService.updateWalletBalance(requestorUid, newRequestorBalance);
|
|
if (!addResult.success) {
|
|
return { success: false, error: 'Failed to add amount to requestor wallet' };
|
|
}
|
|
}
|
|
|
|
// Create transactions
|
|
await TransactionService.sendMoney(requesteeUid, {
|
|
amount,
|
|
recipientName: requestorName,
|
|
recipientPhoneNumber: '',
|
|
recipientType: 'contact',
|
|
recipientId: requestorUid,
|
|
note: `Money request fulfilled for ${requestorName}`,
|
|
});
|
|
|
|
await TransactionService.sendMoney(requestorUid, {
|
|
amount,
|
|
recipientName: requesteeName,
|
|
recipientPhoneNumber: '',
|
|
recipientType: 'contact',
|
|
recipientId: requesteeUid,
|
|
note: `Money request received from ${requesteeName}`,
|
|
});
|
|
}
|
|
|
|
// Update the request status
|
|
const statusUpdateResult = await RequestService.updateRequestStatus(
|
|
requestId,
|
|
action === 'accept' ? 'accepted' : 'declined'
|
|
);
|
|
|
|
if (!statusUpdateResult.success) {
|
|
return { success: false, error: 'Failed to update request status' };
|
|
}
|
|
|
|
return { success: true };
|
|
} catch (error) {
|
|
console.error('Error handling money request response:', error);
|
|
return {
|
|
success: false,
|
|
error: error instanceof Error ? error.message : 'Failed to handle request response',
|
|
};
|
|
}
|
|
}
|
|
}
|