feat: add Expo Push notifications for mobile and configure EXPO_ACCESS_TOKEN
- Backend: add expo_push_tokens table, expo-register/unregister endpoints, hybrid VAPID+Expo push sender - Mobile: register Expo push token on app launch, bell toggle on medicine/pharmacy detail screens - .env.example: document EXPO_ACCESS_TOKEN configuration - Dark mode hover fixes for search suggestions and recent buttons
This commit is contained in:
@@ -2,6 +2,7 @@ import * as Notifications from 'expo-notifications';
|
||||
import * as Device from 'expo-device';
|
||||
import * as Constants from 'expo-constants';
|
||||
import { Platform } from 'react-native';
|
||||
import api from './api';
|
||||
|
||||
Notifications.setNotificationHandler({
|
||||
handleNotification: async () => ({
|
||||
@@ -12,6 +13,8 @@ Notifications.setNotificationHandler({
|
||||
}),
|
||||
});
|
||||
|
||||
let _cachedToken: string | null = null;
|
||||
|
||||
export async function registerForPushNotifications() {
|
||||
if (!Device.isDevice) {
|
||||
console.log('Push notifications require a physical device');
|
||||
@@ -48,6 +51,11 @@ export async function registerForPushNotifications() {
|
||||
projectId,
|
||||
});
|
||||
|
||||
_cachedToken = token.data;
|
||||
|
||||
// Register token with backend (fire and forget)
|
||||
registerTokenWithBackend(token.data).catch(() => {});
|
||||
|
||||
return token.data;
|
||||
} catch (e) {
|
||||
console.log('Error getting push token:', e);
|
||||
@@ -55,6 +63,52 @@ export async function registerForPushNotifications() {
|
||||
}
|
||||
}
|
||||
|
||||
async function registerTokenWithBackend(token: string) {
|
||||
try {
|
||||
await api.post('/notifications/expo-register', { token });
|
||||
} catch (e) {
|
||||
console.log('Failed to register push token with backend:', e);
|
||||
}
|
||||
}
|
||||
|
||||
export async function subscribeToMedicine(
|
||||
medicineNregistro: string,
|
||||
medicineName: string | null,
|
||||
pharmacyId?: number | null
|
||||
) {
|
||||
const token = _cachedToken;
|
||||
if (!token) {
|
||||
console.log('No push token available for subscription');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await api.post('/notifications/expo-register', {
|
||||
token,
|
||||
medicine_nregistro: medicineNregistro,
|
||||
medicine_name: medicineName,
|
||||
pharmacy_id: pharmacyId || null,
|
||||
});
|
||||
} catch (e) {
|
||||
console.log('Failed to subscribe to medicine notifications:', e);
|
||||
}
|
||||
}
|
||||
|
||||
export async function unsubscribeFromMedicine(
|
||||
medicineNregistro: string,
|
||||
pharmacyId?: number | null
|
||||
) {
|
||||
try {
|
||||
await api.delete('/notifications/expo-unregister', {
|
||||
data: {
|
||||
medicine_nregistro: medicineNregistro,
|
||||
pharmacy_id: pharmacyId || null,
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
console.log('Failed to unsubscribe from medicine notifications:', e);
|
||||
}
|
||||
}
|
||||
|
||||
export async function scheduleMedicineAvailabilityNotification(
|
||||
medicineName: string,
|
||||
pharmacyName: string
|
||||
|
||||
Reference in New Issue
Block a user