enh
This commit is contained in:
parent
2a106b5467
commit
31395e5cc7
6 changed files with 70 additions and 132 deletions
|
|
@ -348,12 +348,17 @@ export default function OrderDetails() {
|
|||
)}
|
||||
|
||||
{/* Customer Details */}
|
||||
<View
|
||||
<TouchableOpacity
|
||||
onPress={() => 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`}
|
||||
>
|
||||
<MyText style={tw`text-base font-bold text-gray-900 mb-4`}>
|
||||
<View style={tw`flex-row items-center justify-between mb-4`}>
|
||||
<MyText style={tw`text-base font-bold text-gray-900`}>
|
||||
Customer Details
|
||||
</MyText>
|
||||
<MaterialIcons name="chevron-right" size={20} color="#6B7280" />
|
||||
</View>
|
||||
|
||||
<View style={tw`flex-row items-center mb-4`}>
|
||||
<View
|
||||
|
|
@ -363,7 +368,7 @@ export default function OrderDetails() {
|
|||
</View>
|
||||
<View>
|
||||
<MyText style={tw`text-sm font-bold text-gray-900`}>
|
||||
{order.customerName}
|
||||
{order.customerName || 'Unknown User'}
|
||||
</MyText>
|
||||
<MyText style={tw`text-xs text-gray-500`}>Customer</MyText>
|
||||
</View>
|
||||
|
|
@ -404,7 +409,7 @@ export default function OrderDetails() {
|
|||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
|
||||
{/* Order Items */}
|
||||
<View
|
||||
|
|
|
|||
|
|
@ -187,23 +187,6 @@ export default function SendNotifications() {
|
|||
</View>
|
||||
|
||||
<ScrollView style={tw`flex-1`} contentContainerStyle={tw`p-4`}>
|
||||
{/* User Selection */}
|
||||
<View style={tw`bg-white rounded-xl border border-gray-100 p-4 mb-4 shadow-sm`}>
|
||||
<MyText style={tw`text-base font-bold text-gray-900 mb-3`}>Select Users</MyText>
|
||||
<BottomDropdown
|
||||
label="Select Users"
|
||||
value={selectedUserIds}
|
||||
options={dropdownOptions}
|
||||
onValueChange={(value) => setSelectedUserIds(value as number[])}
|
||||
multiple={true}
|
||||
placeholder="Select users"
|
||||
onSearch={(query) => setSearchQuery(query)}
|
||||
/>
|
||||
<MyText style={tw`text-gray-500 text-sm mt-2`}>
|
||||
{getDisplayText()}
|
||||
</MyText>
|
||||
</View>
|
||||
|
||||
{/* Title Input */}
|
||||
<View style={tw`bg-white rounded-xl border border-gray-100 p-4 mb-4 shadow-sm`}>
|
||||
<MyText style={tw`text-base font-bold text-gray-900 mb-3`}>Title</MyText>
|
||||
|
|
@ -228,8 +211,8 @@ export default function SendNotifications() {
|
|||
/>
|
||||
</View>
|
||||
|
||||
{/* Image Upload */}
|
||||
<View style={tw`bg-white rounded-xl border border-gray-100 p-4 mb-4 shadow-sm`}>
|
||||
{/* Image Upload - Hidden for now */}
|
||||
{/* <View style={tw`bg-white rounded-xl border border-gray-100 p-4 mb-4 shadow-sm`}>
|
||||
<MyText style={tw`text-base font-bold text-gray-900 mb-3`}>Image (Optional)</MyText>
|
||||
<ImageUploader
|
||||
images={displayImage ? [displayImage] : []}
|
||||
|
|
@ -237,6 +220,23 @@ export default function SendNotifications() {
|
|||
onAddImage={handleImagePick}
|
||||
onRemoveImage={handleRemoveImage}
|
||||
/>
|
||||
</View> */}
|
||||
|
||||
{/* User Selection */}
|
||||
<View style={tw`bg-white rounded-xl border border-gray-100 p-4 mb-4 shadow-sm`}>
|
||||
<MyText style={tw`text-base font-bold text-gray-900 mb-3`}>Select Users (Optional)</MyText>
|
||||
<BottomDropdown
|
||||
label="Select Users"
|
||||
value={selectedUserIds}
|
||||
options={dropdownOptions}
|
||||
onValueChange={(value) => setSelectedUserIds(value as number[])}
|
||||
multiple={true}
|
||||
placeholder="Select users"
|
||||
onSearch={(query) => setSearchQuery(query)}
|
||||
/>
|
||||
<MyText style={tw`text-gray-500 text-sm mt-2`}>
|
||||
{getDisplayText()}
|
||||
</MyText>
|
||||
</View>
|
||||
|
||||
{/* Submit Button */}
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -5,14 +5,8 @@ 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';
|
||||
|
||||
async function createUserByMobile(mobile: string): Promise<typeof users.$inferSelect> {
|
||||
// Clean mobile number (remove non-digits)
|
||||
const cleanMobile = mobile.replace(/\D/g, '');
|
||||
|
|
@ -401,55 +395,7 @@ export const userRouter = {
|
|||
// Generate signed URL for image if provided
|
||||
const signedImageUrl = imageUrl ? await generateSignedUrlFromS3Url(imageUrl) : null;
|
||||
|
||||
let sentCount = 0;
|
||||
let failedCount = 0;
|
||||
|
||||
if (NOTIFICATION_PROVIDER === 'fcm') {
|
||||
// Build FCM messages
|
||||
const messages = tokens.map(({ token }) => ({
|
||||
token: token,
|
||||
notification: {
|
||||
title: 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)
|
||||
// Send using Expo
|
||||
const expo = new Expo();
|
||||
|
||||
// Helper function to chunk array
|
||||
|
|
@ -462,6 +408,8 @@ export const userRouter = {
|
|||
};
|
||||
|
||||
const chunks = chunkArray(tokens, 50);
|
||||
let sentCount = 0;
|
||||
let failedCount = 0;
|
||||
|
||||
for (const chunk of chunks) {
|
||||
const messages = chunk
|
||||
|
|
@ -492,7 +440,6 @@ export const userRouter = {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue