diff --git a/apps/admin-ui/app/(drawer)/order-details/[id].tsx b/apps/admin-ui/app/(drawer)/order-details/[id].tsx index d95d86d..78c6dd5 100644 --- a/apps/admin-ui/app/(drawer)/order-details/[id].tsx +++ b/apps/admin-ui/app/(drawer)/order-details/[id].tsx @@ -348,12 +348,17 @@ export default function OrderDetails() { )} {/* Customer Details */} - order.userId && router.push(`/(drawer)/user-management/${order.userId}`)} + activeOpacity={0.7} style={tw`bg-white p-5 rounded-2xl shadow-sm mb-4 border border-gray-100`} > - - Customer Details - + + + Customer Details + + + - {order.customerName} + {order.customerName || 'Unknown User'} Customer @@ -404,7 +409,7 @@ export default function OrderDetails() { - + {/* Order Items */} - {/* User Selection */} - - Select Users - setSelectedUserIds(value as number[])} - multiple={true} - placeholder="Select users" - onSearch={(query) => setSearchQuery(query)} - /> - - {getDisplayText()} - - - {/* Title Input */} Title @@ -228,8 +211,8 @@ export default function SendNotifications() { /> - {/* Image Upload */} - + {/* Image Upload - Hidden for now */} + {/* Image (Optional) + */} + + {/* User Selection */} + + Select Users (Optional) + setSelectedUserIds(value as number[])} + multiple={true} + placeholder="Select users" + onSearch={(query) => setSearchQuery(query)} + /> + + {getDisplayText()} + {/* Submit Button */} diff --git a/apps/backend/package.json b/apps/backend/package.json index aa3f117..46c36d6 100755 --- a/apps/backend/package.json +++ b/apps/backend/package.json @@ -37,7 +37,6 @@ "drizzle-orm": "^0.44.5", "expo-server-sdk": "^4.0.0", "express": "^5.1.0", - "firebase-admin": "^13.6.1", "fuse.js": "^7.1.0", "jsonwebtoken": "^9.0.2", "multer": "^2.0.2", diff --git a/apps/backend/src/lib/firebase.ts b/apps/backend/src/lib/firebase.ts deleted file mode 100644 index c590e91..0000000 --- a/apps/backend/src/lib/firebase.ts +++ /dev/null @@ -1,14 +0,0 @@ -import admin from 'firebase-admin'; -import path from 'path'; - -// // Initialize Firebase Admin SDK -// const serviceAccountPath = path.join('.', 'creds', 'fcm-v1-account.json'); - -// if (!admin.apps.length) { -// admin.initializeApp({ -// credential: admin.credential.cert(serviceAccountPath), -// }); -// } - -// export const messaging = admin.messaging(); -// export default admin; diff --git a/apps/backend/src/trpc/admin-apis/order.ts b/apps/backend/src/trpc/admin-apis/order.ts index cd84fa2..e4a6e1c 100644 --- a/apps/backend/src/trpc/admin-apis/order.ts +++ b/apps/backend/src/trpc/admin-apis/order.ts @@ -304,6 +304,7 @@ export const orderRouter = router({ return { id: orderData.id, readableId: orderData.id, + userId: orderData.user.id, customerName: `${orderData.user.name}`, customerEmail: orderData.user.email, customerMobile: orderData.user.mobile, diff --git a/apps/backend/src/trpc/admin-apis/user.ts b/apps/backend/src/trpc/admin-apis/user.ts index 99723b4..d02861e 100644 --- a/apps/backend/src/trpc/admin-apis/user.ts +++ b/apps/backend/src/trpc/admin-apis/user.ts @@ -5,13 +5,7 @@ import { users, complaints, orders, orderItems, notifCreds, userNotifications, u import { eq, sql, desc, asc, count, max } from 'drizzle-orm'; import { ApiError } from '../../lib/api-error'; import { Expo } from 'expo-server-sdk'; -// import { messaging } from '../../lib/firebase'; -import { generateSignedUrlFromS3Url } from '../../lib/s3-client'; - -// Toggle between notification providers: 'expo' | 'fcm' -// const NOTIFICATION_PROVIDER: 'expo' | 'fcm' = 'fcm'; -// let NOTIFICATION_PROVIDER: 'expo' | 'fcm' = 'expo'; -let NOTIFICATION_PROVIDER: string = 'expo'; +import { generateSignedUrlFromS3Url } from '../../lib/s3-client'; async function createUserByMobile(mobile: string): Promise { // Clean mobile number (remove non-digits) @@ -401,95 +395,48 @@ export const userRouter = { // Generate signed URL for image if provided const signedImageUrl = imageUrl ? await generateSignedUrlFromS3Url(imageUrl) : null; + // Send using Expo + const expo = new Expo(); + + // Helper function to chunk array + const chunkArray = (array: any[], size: number) => { + const chunks = []; + for (let i = 0; i < array.length; i += size) { + chunks.push(array.slice(i, i + size)); + } + return chunks; + }; + + const chunks = chunkArray(tokens, 50); let sentCount = 0; let failedCount = 0; - - if (NOTIFICATION_PROVIDER === 'fcm') { - // Build FCM messages - const messages = tokens.map(({ token }) => ({ - token: token, - notification: { - title: title, + + for (const chunk of chunks) { + const messages = chunk + .filter(({ token }) => Expo.isExpoPushToken(token)) + .map(({ token }) => ({ + to: token, + sound: 'default', + title, body: text, - }, - data: { - imageUrl: imageUrl || '', - }, - android: { - notification: { - imageUrl: signedImageUrl || undefined, - }, - }, - apns: { - payload: { - aps: { - 'mutable-content': 1, - }, - }, - fcm_options: { - image: signedImageUrl || undefined, - }, - }, - })); - - // Send notifications using Firebase Admin SDK - try { - // const response = await messaging.sendEach(messages); - // sentCount = response.successCount; - // failedCount = response.failureCount; - - // // Log failed tokens - // response.responses.forEach((resp, idx) => { - // if (!resp.success) { - // console.error(`Failed to send to token ${tokens[idx].token}:`, resp.error); - // } - // }); - } catch (error) { - console.error('Error sending push notifications:', error); - throw new ApiError('Failed to send push notifications', 500); - } - } else { - // Send using Expo (legacy) - const expo = new Expo(); + data: { imageUrl }, + ...(signedImageUrl ? { + attachments: [ + { + url: signedImageUrl, + contentType: 'image/jpeg', + } + ] + } : {}), + })); - // Helper function to chunk array - const chunkArray = (array: any[], size: number) => { - const chunks = []; - for (let i = 0; i < array.length; i += size) { - chunks.push(array.slice(i, i + size)); - } - return chunks; - }; - - const chunks = chunkArray(tokens, 50); - - for (const chunk of chunks) { - const messages = chunk - .filter(({ token }) => Expo.isExpoPushToken(token)) - .map(({ token }) => ({ - to: token, - sound: 'default', - title, - body: text, - data: { imageUrl }, - ...(signedImageUrl ? { - attachments: [ - { - url: signedImageUrl, - contentType: 'image/jpeg', - } - ] - } : {}), - })); - - if (messages.length > 0) { - try { - await expo.sendPushNotificationsAsync(messages); - sentCount += messages.length; - } catch (error) { - console.error('Error sending push notifications:', error); - failedCount += chunk.length; - } + if (messages.length > 0) { + try { + await expo.sendPushNotificationsAsync(messages); + sentCount += messages.length; + } catch (error) { + console.error('Error sending push notifications:', error); + failedCount += chunk.length; } } }