shared-features 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/{admin-commonFeatures-B3ncUJ8f.js → admin-commonFeatures-BKjytwx5.js} +3 -3
  2. package/dist/{admin-commonFeatures-B3ncUJ8f.js.map → admin-commonFeatures-BKjytwx5.js.map} +1 -1
  3. package/dist/{admin-commonFeatures-BSLz4WzX.cjs → admin-commonFeatures-bjszYcI3.cjs} +3 -3
  4. package/dist/{admin-commonFeatures-BSLz4WzX.cjs.map → admin-commonFeatures-bjszYcI3.cjs.map} +1 -1
  5. package/dist/{broadcasts-EUg3P5xI.cjs → broadcasts-BeTm29_q.cjs} +2 -2
  6. package/dist/{broadcasts-EUg3P5xI.cjs.map → broadcasts-BeTm29_q.cjs.map} +1 -1
  7. package/dist/{broadcasts-S0lssxEi.js → broadcasts-CbrWZpcI.js} +2 -2
  8. package/dist/{broadcasts-S0lssxEi.js.map → broadcasts-CbrWZpcI.js.map} +1 -1
  9. package/dist/{commonFeatures-0REcW-rc.js → commonFeatures-78YVrQq1.js} +55 -27
  10. package/dist/commonFeatures-78YVrQq1.js.map +1 -0
  11. package/dist/{commonFeatures-CgwtnzBH.cjs → commonFeatures-DMYLR629.cjs} +55 -27
  12. package/dist/commonFeatures-DMYLR629.cjs.map +1 -0
  13. package/dist/components/index.cjs +1 -1
  14. package/dist/components/index.js +1 -1
  15. package/dist/{featureFlags-DwdK0wVR.js → featureFlags-DLdibcv_.js} +14 -10
  16. package/dist/featureFlags-DLdibcv_.js.map +1 -0
  17. package/dist/{featureFlags-CvgDQGL0.cjs → featureFlags-DOwy_uOj.cjs} +14 -10
  18. package/dist/featureFlags-DOwy_uOj.cjs.map +1 -0
  19. package/dist/hooks/index.cjs +2 -2
  20. package/dist/hooks/index.js +2 -2
  21. package/dist/{index-4zy9lWZc.cjs → index-B5uAGS9G.cjs} +3 -3
  22. package/dist/{index-4zy9lWZc.cjs.map → index-B5uAGS9G.cjs.map} +1 -1
  23. package/dist/{index-BxdTtnwy.js → index-CQNjI6V7.js} +3 -3
  24. package/dist/{index-BxdTtnwy.js.map → index-CQNjI6V7.js.map} +1 -1
  25. package/dist/index.cjs +7 -7
  26. package/dist/index.js +7 -7
  27. package/dist/services/commonFeatures.d.ts.map +1 -1
  28. package/dist/services/index.cjs +4 -4
  29. package/dist/services/index.js +4 -4
  30. package/dist/types/commonFeatures.d.ts +7 -4
  31. package/dist/types/commonFeatures.d.ts.map +1 -1
  32. package/dist/types/index.cjs +1 -1
  33. package/dist/types/index.js +1 -1
  34. package/dist/{useCommonFeatures-CCaKh0xS.js → useCommonFeatures-BVaPDaPy.js} +2 -2
  35. package/dist/{useCommonFeatures-CCaKh0xS.js.map → useCommonFeatures-BVaPDaPy.js.map} +1 -1
  36. package/dist/{useCommonFeatures-BHxIYxPB.cjs → useCommonFeatures-NobppaW9.cjs} +2 -2
  37. package/dist/{useCommonFeatures-BHxIYxPB.cjs.map → useCommonFeatures-NobppaW9.cjs.map} +1 -1
  38. package/dist/{useFeatureFlags-B6Vz-BSk.cjs → useFeatureFlags-8nC71ue-.cjs} +3 -3
  39. package/dist/{useFeatureFlags-B6Vz-BSk.cjs.map → useFeatureFlags-8nC71ue-.cjs.map} +1 -1
  40. package/dist/{useFeatureFlags-XCAyrfLp.js → useFeatureFlags-DlMeLBH2.js} +3 -3
  41. package/dist/{useFeatureFlags-XCAyrfLp.js.map → useFeatureFlags-DlMeLBH2.js.map} +1 -1
  42. package/package.json +1 -1
  43. package/dist/commonFeatures-0REcW-rc.js.map +0 -1
  44. package/dist/commonFeatures-CgwtnzBH.cjs.map +0 -1
  45. package/dist/featureFlags-CvgDQGL0.cjs.map +0 -1
  46. package/dist/featureFlags-DwdK0wVR.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  import { query, collection, where, Timestamp, getDocs, getDoc, doc, orderBy, deleteDoc, updateDoc, serverTimestamp, addDoc, setDoc } from "firebase/firestore";
2
- import { L as getSharedFeaturesDb, h as clearPaymentOptionsCache, j as clearProjectsCache, k as clearServicesCache, l as clearSkillsCache, m as clearSocialLinksCache, n as clearTestimonialsCache, a as clearAddressInfoCache, e as clearContactInfoCache, f as clearDeveloperInfoCache } from "./commonFeatures-0REcW-rc.js";
3
- import { a as COMMON_FEATURE_COLLECTIONS } from "./featureFlags-DwdK0wVR.js";
2
+ import { L as getSharedFeaturesDb, h as clearPaymentOptionsCache, j as clearProjectsCache, k as clearServicesCache, l as clearSkillsCache, m as clearSocialLinksCache, n as clearTestimonialsCache, a as clearAddressInfoCache, e as clearContactInfoCache, f as clearDeveloperInfoCache } from "./commonFeatures-78YVrQq1.js";
3
+ import { a as COMMON_FEATURE_COLLECTIONS } from "./featureFlags-DLdibcv_.js";
4
4
  const COLLECTION_BROADCASTS = "zaions_broadcasts";
5
5
  const COLLECTION_TEMPLATES = "zaions_notification_templates";
6
6
  const COLLECTION_BROADCAST_EVENTS = "zaions_broadcast_events";
@@ -727,4 +727,4 @@ export {
727
727
  getTemplateById as y,
728
728
  pauseBroadcast as z
729
729
  };
730
- //# sourceMappingURL=admin-commonFeatures-B3ncUJ8f.js.map
730
+ //# sourceMappingURL=admin-commonFeatures-BKjytwx5.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"admin-commonFeatures-B3ncUJ8f.js","sources":["../src/services/admin-notifications.ts","../src/services/admin-commonFeatures.ts"],"sourcesContent":["/**\n * Admin Notifications Service\n *\n * Service for managing broadcasts and templates from the admin panel.\n * Used in aoneahsan.com admin panel to manage cross-project notifications.\n *\n * @author Ahsan Mahmood <aoneahsan@gmail.com>\n */\n\nimport {\n collection,\n doc,\n getDocs,\n getDoc,\n updateDoc,\n deleteDoc,\n addDoc,\n query,\n where,\n orderBy,\n serverTimestamp,\n Timestamp,\n} from 'firebase/firestore';\nimport { getSharedFeaturesDb } from '../firebase/init';\nimport type {\n BroadcastNotification,\n BroadcastStatus,\n CreateBroadcastInput,\n UpdateBroadcastInput,\n NotificationTemplate,\n CreateTemplateInput,\n BroadcastAnalytics,\n NotificationAnalytics,\n} from '../types/notifications';\n\n// ============================================================================\n// CONSTANTS\n// ============================================================================\n\nconst COLLECTION_BROADCASTS = 'zaions_broadcasts';\nconst COLLECTION_TEMPLATES = 'zaions_notification_templates';\nconst COLLECTION_BROADCAST_EVENTS = 'zaions_broadcast_events';\n\n// ============================================================================\n// HELPER FUNCTIONS\n// ============================================================================\n\n/**\n * Convert Firestore document to BroadcastNotification\n */\nfunction docToBroadcast(\n docId: string,\n data: Record<string, unknown>\n): BroadcastNotification {\n return {\n id: docId,\n title: data.title as string,\n message: data.message as string,\n type: data.type as BroadcastNotification['type'],\n category: data.category as BroadcastNotification['category'],\n isRead: false,\n isImportant: data.isImportant as boolean | undefined,\n actionUrl: data.actionUrl as string | undefined,\n actionText: data.actionText as string | undefined,\n createdAt: data.createdAt as Timestamp,\n metadata: data.metadata as Record<string, unknown> | undefined,\n targetProjects: (data.targetProjects as string[]) || [],\n targetPlatforms: (data.targetPlatforms as BroadcastNotification['targetPlatforms']) || [],\n targetAudience: (data.targetAudience as BroadcastNotification['targetAudience']) || 'all',\n status: data.status as BroadcastStatus,\n startDate: data.startDate as Timestamp,\n endDate: data.endDate as Timestamp | null | undefined,\n priority: (data.priority as number) || 50,\n dismissible: data.dismissible !== false,\n variant: (data.variant as BroadcastNotification['variant']) || 'banner',\n impressions: (data.impressions as number) || 0,\n clicks: (data.clicks as number) || 0,\n createdBy: data.createdBy as string,\n updatedBy: data.updatedBy as string | undefined,\n };\n}\n\n/**\n * Convert Firestore document to NotificationTemplate\n */\nfunction docToTemplate(\n docId: string,\n data: Record<string, unknown>\n): NotificationTemplate {\n return {\n id: docId,\n name: data.name as string,\n eventType: data.eventType as string,\n category: data.category as NotificationTemplate['category'],\n title: data.title as string,\n message: data.message as string,\n variables: (data.variables as string[]) || [],\n type: data.type as NotificationTemplate['type'],\n isImportant: data.isImportant as boolean,\n actionUrl: data.actionUrl as string | undefined,\n actionText: data.actionText as string | undefined,\n enabled: data.enabled !== false,\n createdAt: (data.createdAt as Timestamp)?.toDate() || new Date(),\n updatedAt: (data.updatedAt as Timestamp)?.toDate() || new Date(),\n };\n}\n\n// ============================================================================\n// BROADCAST CRUD\n// ============================================================================\n\n/**\n * Create a new broadcast\n */\nexport async function createBroadcast(\n input: CreateBroadcastInput,\n adminUserId: string\n): Promise<string> {\n const db = getSharedFeaturesDb();\n\n const broadcastData = {\n ...input,\n status: 'draft' as BroadcastStatus,\n isRead: false,\n impressions: 0,\n clicks: 0,\n createdBy: adminUserId,\n createdAt: serverTimestamp(),\n startDate: Timestamp.fromDate(input.startDate),\n endDate: input.endDate ? Timestamp.fromDate(input.endDate) : null,\n };\n\n const docRef = await addDoc(\n collection(db, COLLECTION_BROADCASTS),\n broadcastData\n );\n\n return docRef.id;\n}\n\n/**\n * Update an existing broadcast\n */\nexport async function updateBroadcast(\n input: UpdateBroadcastInput,\n adminUserId: string\n): Promise<void> {\n const db = getSharedFeaturesDb();\n\n const updateData: Record<string, unknown> = {\n ...input,\n updatedBy: adminUserId,\n updatedAt: serverTimestamp(),\n };\n\n // Convert dates if provided\n if (input.startDate) {\n updateData.startDate = Timestamp.fromDate(input.startDate);\n }\n if (input.endDate !== undefined) {\n updateData.endDate = input.endDate ? Timestamp.fromDate(input.endDate) : null;\n }\n\n // Remove id from update data\n delete updateData.id;\n\n await updateDoc(doc(db, COLLECTION_BROADCASTS, input.id), updateData);\n}\n\n/**\n * Delete a broadcast\n */\nexport async function deleteBroadcast(broadcastId: string): Promise<void> {\n const db = getSharedFeaturesDb();\n await deleteDoc(doc(db, COLLECTION_BROADCASTS, broadcastId));\n}\n\n/**\n * Get all broadcasts (for admin listing)\n */\nexport async function getAllBroadcasts(): Promise<BroadcastNotification[]> {\n const db = getSharedFeaturesDb();\n\n const q = query(\n collection(db, COLLECTION_BROADCASTS),\n orderBy('createdAt', 'desc')\n );\n\n const snapshot = await getDocs(q);\n return snapshot.docs.map((d) => docToBroadcast(d.id, d.data()));\n}\n\n/**\n * Get broadcasts by status\n */\nexport async function getBroadcastsByStatus(\n status: BroadcastStatus\n): Promise<BroadcastNotification[]> {\n const db = getSharedFeaturesDb();\n\n const q = query(\n collection(db, COLLECTION_BROADCASTS),\n where('status', '==', status),\n orderBy('createdAt', 'desc')\n );\n\n const snapshot = await getDocs(q);\n return snapshot.docs.map((d) => docToBroadcast(d.id, d.data()));\n}\n\n/**\n * Get a single broadcast by ID\n */\nexport async function getBroadcastById(\n broadcastId: string\n): Promise<BroadcastNotification | null> {\n const db = getSharedFeaturesDb();\n const docSnap = await getDoc(doc(db, COLLECTION_BROADCASTS, broadcastId));\n\n if (!docSnap.exists()) return null;\n return docToBroadcast(docSnap.id, docSnap.data());\n}\n\n// ============================================================================\n// BROADCAST STATUS MANAGEMENT\n// ============================================================================\n\n/**\n * Publish a draft broadcast (set to active)\n */\nexport async function publishBroadcast(\n broadcastId: string,\n adminUserId: string\n): Promise<void> {\n const db = getSharedFeaturesDb();\n\n await updateDoc(doc(db, COLLECTION_BROADCASTS, broadcastId), {\n status: 'active',\n updatedBy: adminUserId,\n updatedAt: serverTimestamp(),\n });\n}\n\n/**\n * Schedule a broadcast for later\n */\nexport async function scheduleBroadcast(\n broadcastId: string,\n scheduledDate: Date,\n adminUserId: string\n): Promise<void> {\n const db = getSharedFeaturesDb();\n\n await updateDoc(doc(db, COLLECTION_BROADCASTS, broadcastId), {\n status: 'scheduled',\n startDate: Timestamp.fromDate(scheduledDate),\n updatedBy: adminUserId,\n updatedAt: serverTimestamp(),\n });\n}\n\n/**\n * Pause an active broadcast\n */\nexport async function pauseBroadcast(\n broadcastId: string,\n adminUserId: string\n): Promise<void> {\n const db = getSharedFeaturesDb();\n\n await updateDoc(doc(db, COLLECTION_BROADCASTS, broadcastId), {\n status: 'draft', // Move back to draft\n updatedBy: adminUserId,\n updatedAt: serverTimestamp(),\n });\n}\n\n/**\n * End a broadcast\n */\nexport async function endBroadcast(\n broadcastId: string,\n adminUserId: string\n): Promise<void> {\n const db = getSharedFeaturesDb();\n\n await updateDoc(doc(db, COLLECTION_BROADCASTS, broadcastId), {\n status: 'ended',\n endDate: serverTimestamp(),\n updatedBy: adminUserId,\n updatedAt: serverTimestamp(),\n });\n}\n\n// ============================================================================\n// TEMPLATE CRUD\n// ============================================================================\n\n/**\n * Create a new template\n */\nexport async function createTemplate(\n input: CreateTemplateInput\n): Promise<string> {\n const db = getSharedFeaturesDb();\n\n const templateData = {\n ...input,\n createdAt: serverTimestamp(),\n updatedAt: serverTimestamp(),\n };\n\n const docRef = await addDoc(\n collection(db, COLLECTION_TEMPLATES),\n templateData\n );\n\n return docRef.id;\n}\n\n/**\n * Update an existing template\n */\nexport async function updateTemplate(\n templateId: string,\n input: Partial<CreateTemplateInput>\n): Promise<void> {\n const db = getSharedFeaturesDb();\n\n await updateDoc(doc(db, COLLECTION_TEMPLATES, templateId), {\n ...input,\n updatedAt: serverTimestamp(),\n });\n}\n\n/**\n * Delete a template\n */\nexport async function deleteTemplate(templateId: string): Promise<void> {\n const db = getSharedFeaturesDb();\n await deleteDoc(doc(db, COLLECTION_TEMPLATES, templateId));\n}\n\n/**\n * Get all templates\n */\nexport async function getAllTemplates(): Promise<NotificationTemplate[]> {\n const db = getSharedFeaturesDb();\n\n const q = query(\n collection(db, COLLECTION_TEMPLATES),\n orderBy('name', 'asc')\n );\n\n const snapshot = await getDocs(q);\n return snapshot.docs.map((d) => docToTemplate(d.id, d.data()));\n}\n\n/**\n * Get template by ID\n */\nexport async function getTemplateById(\n templateId: string\n): Promise<NotificationTemplate | null> {\n const db = getSharedFeaturesDb();\n const docSnap = await getDoc(doc(db, COLLECTION_TEMPLATES, templateId));\n\n if (!docSnap.exists()) return null;\n return docToTemplate(docSnap.id, docSnap.data());\n}\n\n/**\n * Get template by event type from Firestore\n */\nexport async function getFirestoreTemplateByEventType(\n eventType: string\n): Promise<NotificationTemplate | null> {\n const db = getSharedFeaturesDb();\n\n const q = query(\n collection(db, COLLECTION_TEMPLATES),\n where('eventType', '==', eventType)\n );\n\n const snapshot = await getDocs(q);\n if (snapshot.empty) return null;\n\n const docSnap = snapshot.docs[0];\n if (!docSnap) return null;\n\n return docToTemplate(docSnap.id, docSnap.data());\n}\n\n// ============================================================================\n// ANALYTICS\n// ============================================================================\n\n/**\n * Get analytics for a specific broadcast\n */\nexport async function getBroadcastAnalytics(\n broadcastId: string\n): Promise<BroadcastAnalytics | null> {\n const db = getSharedFeaturesDb();\n\n // Get broadcast\n const broadcast = await getBroadcastById(broadcastId);\n if (!broadcast) return null;\n\n // Get events\n const eventsQuery = query(\n collection(db, COLLECTION_BROADCAST_EVENTS),\n where('broadcastId', '==', broadcastId)\n );\n\n const eventsSnapshot = await getDocs(eventsQuery);\n const events = eventsSnapshot.docs.map((d) => d.data());\n\n // Calculate analytics\n const impressions = events.filter((e) => e.action === 'impression').length;\n const clicks = events.filter((e) => e.action === 'click').length;\n const dismissals = events.filter((e) => e.action === 'dismiss').length;\n\n // Group by platform\n const byPlatform: BroadcastAnalytics['byPlatform'] = {\n web: { impressions: 0, clicks: 0 },\n android: { impressions: 0, clicks: 0 },\n ios: { impressions: 0, clicks: 0 },\n };\n\n events.forEach((e) => {\n const platform = e.platform as keyof typeof byPlatform;\n if (byPlatform[platform]) {\n if (e.action === 'impression') byPlatform[platform].impressions++;\n if (e.action === 'click') byPlatform[platform].clicks++;\n }\n });\n\n // Group by project\n const byProject: BroadcastAnalytics['byProject'] = {};\n events.forEach((e) => {\n const projectId = e.projectId as string;\n if (!byProject[projectId]) {\n byProject[projectId] = { impressions: 0, clicks: 0 };\n }\n if (e.action === 'impression') byProject[projectId].impressions++;\n if (e.action === 'click') byProject[projectId].clicks++;\n });\n\n // Group by date\n const byDateMap: Record<string, { impressions: number; clicks: number }> = {};\n events.forEach((e) => {\n const dateStr = (e.timestamp as Timestamp).toDate().toISOString().split('T')[0];\n if (dateStr) {\n if (!byDateMap[dateStr]) {\n byDateMap[dateStr] = { impressions: 0, clicks: 0 };\n }\n if (e.action === 'impression') byDateMap[dateStr].impressions++;\n if (e.action === 'click') byDateMap[dateStr].clicks++;\n }\n });\n\n const byDate = Object.entries(byDateMap).map(([date, data]) => ({\n date,\n impressions: data.impressions,\n clicks: data.clicks,\n }));\n\n return {\n broadcastId,\n title: broadcast.title,\n status: broadcast.status,\n impressions,\n clicks,\n dismissals,\n ctr: impressions > 0 ? clicks / impressions : 0,\n byPlatform,\n byProject,\n byDate,\n };\n}\n\n/**\n * Get overall notification analytics\n */\nexport async function getOverallAnalytics(\n startDate: Date,\n endDate: Date\n): Promise<NotificationAnalytics> {\n const db = getSharedFeaturesDb();\n\n // Get all broadcast events in date range\n const eventsQuery = query(\n collection(db, COLLECTION_BROADCAST_EVENTS),\n where('timestamp', '>=', Timestamp.fromDate(startDate)),\n where('timestamp', '<=', Timestamp.fromDate(endDate))\n );\n\n const eventsSnapshot = await getDocs(eventsQuery);\n const events = eventsSnapshot.docs.map((d) => d.data());\n\n // Calculate totals\n const totalSent = events.filter((e) => e.action === 'impression').length;\n const totalRead = events.filter((e) => e.action === 'impression').length; // Impressions = read for broadcasts\n const totalClicked = events.filter((e) => e.action === 'click').length;\n\n // Initialize category and type breakdowns\n const byCategory: NotificationAnalytics['byCategory'] = {\n system: { sent: 0, read: 0, clicked: 0 },\n account: { sent: 0, read: 0, clicked: 0 },\n activity: { sent: 0, read: 0, clicked: 0 },\n report: { sent: 0, read: 0, clicked: 0 },\n promotional: { sent: 0, read: 0, clicked: 0 },\n social: { sent: 0, read: 0, clicked: 0 },\n };\n\n const byType: NotificationAnalytics['byType'] = {\n info: { sent: 0, read: 0, clicked: 0 },\n success: { sent: 0, read: 0, clicked: 0 },\n warning: { sent: 0, read: 0, clicked: 0 },\n error: { sent: 0, read: 0, clicked: 0 },\n reminder: { sent: 0, read: 0, clicked: 0 },\n milestone: { sent: 0, read: 0, clicked: 0 },\n announcement: { sent: 0, read: 0, clicked: 0 },\n };\n\n // Group by date\n const byDateMap: Record<string, { sent: number; read: number; clicked: number }> = {};\n events.forEach((e) => {\n const dateStr = (e.timestamp as Timestamp).toDate().toISOString().split('T')[0];\n if (dateStr) {\n if (!byDateMap[dateStr]) {\n byDateMap[dateStr] = { sent: 0, read: 0, clicked: 0 };\n }\n if (e.action === 'impression') {\n byDateMap[dateStr].sent++;\n byDateMap[dateStr].read++;\n }\n if (e.action === 'click') byDateMap[dateStr].clicked++;\n }\n });\n\n const byDate = Object.entries(byDateMap)\n .map(([date, data]) => ({ date, ...data }))\n .sort((a, b) => a.date.localeCompare(b.date));\n\n return {\n totalSent,\n totalRead,\n totalClicked,\n readRate: totalSent > 0 ? totalRead / totalSent : 0,\n clickRate: totalSent > 0 ? totalClicked / totalSent : 0,\n byCategory,\n byType,\n byDate,\n };\n}\n\n// ============================================================================\n// EXPORT SERVICE OBJECT\n// ============================================================================\n\nexport const adminNotificationService = {\n // Broadcasts\n createBroadcast,\n updateBroadcast,\n deleteBroadcast,\n getAllBroadcasts,\n getBroadcastsByStatus,\n getBroadcastById,\n publishBroadcast,\n scheduleBroadcast,\n pauseBroadcast,\n endBroadcast,\n\n // Templates\n createTemplate,\n updateTemplate,\n deleteTemplate,\n getAllTemplates,\n getTemplateById,\n getFirestoreTemplateByEventType,\n\n // Analytics\n getBroadcastAnalytics,\n getOverallAnalytics,\n};\n\nexport default adminNotificationService;\n","/**\n * Admin Common Features Service\n *\n * Admin CRUD operations for managing common features data.\n * These functions modify the zaions_* collections in Firestore.\n *\n * @author Ahsan Mahmood <aoneahsan@gmail.com>\n */\n\nimport {\n doc,\n setDoc,\n updateDoc,\n deleteDoc,\n collection,\n addDoc,\n serverTimestamp,\n} from 'firebase/firestore';\nimport { getSharedFeaturesDb } from '../firebase/init';\nimport {\n COMMON_FEATURE_COLLECTIONS,\n type ContactInfo,\n type DeveloperInfo,\n type AddressInfo,\n type SocialLink,\n type PaymentOption,\n type Service,\n type Skill,\n type Testimonial,\n type Project,\n} from '../types/commonFeatures';\nimport {\n clearContactInfoCache,\n clearDeveloperInfoCache,\n clearAddressInfoCache,\n clearSocialLinksCache,\n clearPaymentOptionsCache,\n clearServicesCache,\n clearSkillsCache,\n clearTestimonialsCache,\n clearProjectsCache,\n} from './commonFeatures';\n\n// ============================================================================\n// CONTACT INFO ADMIN\n// ============================================================================\n\nexport type ContactInfoInput = Omit<ContactInfo, 'id' | 'updatedAt'>;\n\nexport async function saveContactInfo(data: ContactInfoInput): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.CONTACT_INFO, 'main');\n await setDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearContactInfoCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error saving contact info:', error);\n return false;\n }\n}\n\nexport async function updateContactInfo(data: Partial<ContactInfoInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.CONTACT_INFO, 'main');\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearContactInfoCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating contact info:', error);\n return false;\n }\n}\n\n// ============================================================================\n// DEVELOPER INFO ADMIN\n// ============================================================================\n\nexport type DeveloperInfoInput = Omit<DeveloperInfo, 'id' | 'updatedAt'>;\n\nexport async function saveDeveloperInfo(data: DeveloperInfoInput): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.DEVELOPER_INFO, 'main');\n await setDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearDeveloperInfoCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error saving developer info:', error);\n return false;\n }\n}\n\nexport async function updateDeveloperInfo(data: Partial<DeveloperInfoInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.DEVELOPER_INFO, 'main');\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearDeveloperInfoCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating developer info:', error);\n return false;\n }\n}\n\n// ============================================================================\n// ADDRESS INFO ADMIN\n// ============================================================================\n\nexport type AddressInfoInput = Omit<AddressInfo, 'id' | 'updatedAt'>;\n\nexport async function saveAddressInfo(data: AddressInfoInput): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.ADDRESS_INFO, 'main');\n await setDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearAddressInfoCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error saving address info:', error);\n return false;\n }\n}\n\nexport async function updateAddressInfo(data: Partial<AddressInfoInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.ADDRESS_INFO, 'main');\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearAddressInfoCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating address info:', error);\n return false;\n }\n}\n\n// ============================================================================\n// SOCIAL LINKS ADMIN\n// ============================================================================\n\nexport type SocialLinkInput = Omit<SocialLink, 'id' | 'updatedAt'>;\n\nexport async function createSocialLink(data: SocialLinkInput): Promise<string | null> {\n try {\n const db = getSharedFeaturesDb();\n const colRef = collection(db, COMMON_FEATURE_COLLECTIONS.SOCIAL_LINKS);\n const docRef = await addDoc(colRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearSocialLinksCache();\n return docRef.id;\n } catch (error) {\n console.error('[shared-features admin] Error creating social link:', error);\n return null;\n }\n}\n\nexport async function updateSocialLink(id: string, data: Partial<SocialLinkInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.SOCIAL_LINKS, id);\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearSocialLinksCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating social link:', error);\n return false;\n }\n}\n\nexport async function deleteSocialLink(id: string): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.SOCIAL_LINKS, id);\n await deleteDoc(docRef);\n clearSocialLinksCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error deleting social link:', error);\n return false;\n }\n}\n\n// ============================================================================\n// PAYMENT OPTIONS ADMIN\n// ============================================================================\n\nexport type PaymentOptionInput = Omit<PaymentOption, 'id' | 'updatedAt'>;\n\nexport async function createPaymentOption(data: PaymentOptionInput): Promise<string | null> {\n try {\n const db = getSharedFeaturesDb();\n const colRef = collection(db, COMMON_FEATURE_COLLECTIONS.PAYMENT_OPTIONS);\n const docRef = await addDoc(colRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearPaymentOptionsCache();\n return docRef.id;\n } catch (error) {\n console.error('[shared-features admin] Error creating payment option:', error);\n return null;\n }\n}\n\nexport async function updatePaymentOption(id: string, data: Partial<PaymentOptionInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.PAYMENT_OPTIONS, id);\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearPaymentOptionsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating payment option:', error);\n return false;\n }\n}\n\nexport async function deletePaymentOption(id: string): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.PAYMENT_OPTIONS, id);\n await deleteDoc(docRef);\n clearPaymentOptionsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error deleting payment option:', error);\n return false;\n }\n}\n\n// ============================================================================\n// SERVICES ADMIN\n// ============================================================================\n\nexport type ServiceInput = Omit<Service, 'id' | 'updatedAt'>;\n\nexport async function createService(data: ServiceInput): Promise<string | null> {\n try {\n const db = getSharedFeaturesDb();\n const colRef = collection(db, COMMON_FEATURE_COLLECTIONS.SERVICES);\n const docRef = await addDoc(colRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearServicesCache();\n return docRef.id;\n } catch (error) {\n console.error('[shared-features admin] Error creating service:', error);\n return null;\n }\n}\n\nexport async function updateService(id: string, data: Partial<ServiceInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.SERVICES, id);\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearServicesCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating service:', error);\n return false;\n }\n}\n\nexport async function deleteService(id: string): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.SERVICES, id);\n await deleteDoc(docRef);\n clearServicesCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error deleting service:', error);\n return false;\n }\n}\n\n// ============================================================================\n// SKILLS ADMIN\n// ============================================================================\n\nexport type SkillInput = Omit<Skill, 'id' | 'updatedAt'>;\n\nexport async function createSkill(data: SkillInput): Promise<string | null> {\n try {\n const db = getSharedFeaturesDb();\n const colRef = collection(db, COMMON_FEATURE_COLLECTIONS.SKILLS);\n const docRef = await addDoc(colRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearSkillsCache();\n return docRef.id;\n } catch (error) {\n console.error('[shared-features admin] Error creating skill:', error);\n return null;\n }\n}\n\nexport async function updateSkill(id: string, data: Partial<SkillInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.SKILLS, id);\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearSkillsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating skill:', error);\n return false;\n }\n}\n\nexport async function deleteSkill(id: string): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.SKILLS, id);\n await deleteDoc(docRef);\n clearSkillsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error deleting skill:', error);\n return false;\n }\n}\n\n// ============================================================================\n// TESTIMONIALS ADMIN\n// ============================================================================\n\nexport type TestimonialInput = Omit<Testimonial, 'id' | 'updatedAt'>;\n\nexport async function createTestimonial(data: TestimonialInput): Promise<string | null> {\n try {\n const db = getSharedFeaturesDb();\n const colRef = collection(db, COMMON_FEATURE_COLLECTIONS.TESTIMONIALS);\n const docRef = await addDoc(colRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearTestimonialsCache();\n return docRef.id;\n } catch (error) {\n console.error('[shared-features admin] Error creating testimonial:', error);\n return null;\n }\n}\n\nexport async function updateTestimonial(id: string, data: Partial<TestimonialInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.TESTIMONIALS, id);\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearTestimonialsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating testimonial:', error);\n return false;\n }\n}\n\nexport async function deleteTestimonial(id: string): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.TESTIMONIALS, id);\n await deleteDoc(docRef);\n clearTestimonialsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error deleting testimonial:', error);\n return false;\n }\n}\n\n// ============================================================================\n// PROJECTS ADMIN\n// ============================================================================\n\nexport type ProjectInput = Omit<Project, 'id' | 'updatedAt'>;\n\nexport async function createProject(data: ProjectInput): Promise<string | null> {\n try {\n const db = getSharedFeaturesDb();\n const colRef = collection(db, COMMON_FEATURE_COLLECTIONS.PROJECTS);\n const docRef = await addDoc(colRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearProjectsCache();\n return docRef.id;\n } catch (error) {\n console.error('[shared-features admin] Error creating project:', error);\n return null;\n }\n}\n\nexport async function updateProject(id: string, data: Partial<ProjectInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.PROJECTS, id);\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearProjectsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating project:', error);\n return false;\n }\n}\n\nexport async function deleteProject(id: string): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.PROJECTS, id);\n await deleteDoc(docRef);\n clearProjectsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error deleting project:', error);\n return false;\n }\n}\n"],"names":[],"mappings":";;;AAuCA,MAAM,wBAAwB;AAC9B,MAAM,uBAAuB;AAC7B,MAAM,8BAA8B;AASpC,SAAS,eACP,OACA,MACuB;AACvB,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,OAAO,KAAK;AAAA,IACZ,SAAS,KAAK;AAAA,IACd,MAAM,KAAK;AAAA,IACX,UAAU,KAAK;AAAA,IACf,QAAQ;AAAA,IACR,aAAa,KAAK;AAAA,IAClB,WAAW,KAAK;AAAA,IAChB,YAAY,KAAK;AAAA,IACjB,WAAW,KAAK;AAAA,IAChB,UAAU,KAAK;AAAA,IACf,gBAAiB,KAAK,kBAA+B,CAAA;AAAA,IACrD,iBAAkB,KAAK,mBAAgE,CAAA;AAAA,IACvF,gBAAiB,KAAK,kBAA8D;AAAA,IACpF,QAAQ,KAAK;AAAA,IACb,WAAW,KAAK;AAAA,IAChB,SAAS,KAAK;AAAA,IACd,UAAW,KAAK,YAAuB;AAAA,IACvC,aAAa,KAAK,gBAAgB;AAAA,IAClC,SAAU,KAAK,WAAgD;AAAA,IAC/D,aAAc,KAAK,eAA0B;AAAA,IAC7C,QAAS,KAAK,UAAqB;AAAA,IACnC,WAAW,KAAK;AAAA,IAChB,WAAW,KAAK;AAAA,EAAA;AAEpB;AAKA,SAAS,cACP,OACA,MACsB;AACtB,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,MAAM,KAAK;AAAA,IACX,WAAW,KAAK;AAAA,IAChB,UAAU,KAAK;AAAA,IACf,OAAO,KAAK;AAAA,IACZ,SAAS,KAAK;AAAA,IACd,WAAY,KAAK,aAA0B,CAAA;AAAA,IAC3C,MAAM,KAAK;AAAA,IACX,aAAa,KAAK;AAAA,IAClB,WAAW,KAAK;AAAA,IAChB,YAAY,KAAK;AAAA,IACjB,SAAS,KAAK,YAAY;AAAA,IAC1B,WAAY,KAAK,WAAyB,OAAA,yBAAgB,KAAA;AAAA,IAC1D,WAAY,KAAK,WAAyB,OAAA,yBAAgB,KAAA;AAAA,EAAK;AAEnE;AASA,eAAsB,gBACpB,OACA,aACiB;AACjB,QAAM,KAAK,oBAAA;AAEX,QAAM,gBAAgB;AAAA,IACpB,GAAG;AAAA,IACH,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,WAAW,gBAAA;AAAA,IACX,WAAW,UAAU,SAAS,MAAM,SAAS;AAAA,IAC7C,SAAS,MAAM,UAAU,UAAU,SAAS,MAAM,OAAO,IAAI;AAAA,EAAA;AAG/D,QAAM,SAAS,MAAM;AAAA,IACnB,WAAW,IAAI,qBAAqB;AAAA,IACpC;AAAA,EAAA;AAGF,SAAO,OAAO;AAChB;AAKA,eAAsB,gBACpB,OACA,aACe;AACf,QAAM,KAAK,oBAAA;AAEX,QAAM,aAAsC;AAAA,IAC1C,GAAG;AAAA,IACH,WAAW;AAAA,IACX,WAAW,gBAAA;AAAA,EAAgB;AAI7B,MAAI,MAAM,WAAW;AACnB,eAAW,YAAY,UAAU,SAAS,MAAM,SAAS;AAAA,EAC3D;AACA,MAAI,MAAM,YAAY,QAAW;AAC/B,eAAW,UAAU,MAAM,UAAU,UAAU,SAAS,MAAM,OAAO,IAAI;AAAA,EAC3E;AAGA,SAAO,WAAW;AAElB,QAAM,UAAU,IAAI,IAAI,uBAAuB,MAAM,EAAE,GAAG,UAAU;AACtE;AAKA,eAAsB,gBAAgB,aAAoC;AACxE,QAAM,KAAK,oBAAA;AACX,QAAM,UAAU,IAAI,IAAI,uBAAuB,WAAW,CAAC;AAC7D;AAKA,eAAsB,mBAAqD;AACzE,QAAM,KAAK,oBAAA;AAEX,QAAM,IAAI;AAAA,IACR,WAAW,IAAI,qBAAqB;AAAA,IACpC,QAAQ,aAAa,MAAM;AAAA,EAAA;AAG7B,QAAM,WAAW,MAAM,QAAQ,CAAC;AAChC,SAAO,SAAS,KAAK,IAAI,CAAC,MAAM,eAAe,EAAE,IAAI,EAAE,KAAA,CAAM,CAAC;AAChE;AAKA,eAAsB,sBACpB,QACkC;AAClC,QAAM,KAAK,oBAAA;AAEX,QAAM,IAAI;AAAA,IACR,WAAW,IAAI,qBAAqB;AAAA,IACpC,MAAM,UAAU,MAAM,MAAM;AAAA,IAC5B,QAAQ,aAAa,MAAM;AAAA,EAAA;AAG7B,QAAM,WAAW,MAAM,QAAQ,CAAC;AAChC,SAAO,SAAS,KAAK,IAAI,CAAC,MAAM,eAAe,EAAE,IAAI,EAAE,KAAA,CAAM,CAAC;AAChE;AAKA,eAAsB,iBACpB,aACuC;AACvC,QAAM,KAAK,oBAAA;AACX,QAAM,UAAU,MAAM,OAAO,IAAI,IAAI,uBAAuB,WAAW,CAAC;AAExE,MAAI,CAAC,QAAQ,OAAA,EAAU,QAAO;AAC9B,SAAO,eAAe,QAAQ,IAAI,QAAQ,MAAM;AAClD;AASA,eAAsB,iBACpB,aACA,aACe;AACf,QAAM,KAAK,oBAAA;AAEX,QAAM,UAAU,IAAI,IAAI,uBAAuB,WAAW,GAAG;AAAA,IAC3D,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,WAAW,gBAAA;AAAA,EAAgB,CAC5B;AACH;AAKA,eAAsB,kBACpB,aACA,eACA,aACe;AACf,QAAM,KAAK,oBAAA;AAEX,QAAM,UAAU,IAAI,IAAI,uBAAuB,WAAW,GAAG;AAAA,IAC3D,QAAQ;AAAA,IACR,WAAW,UAAU,SAAS,aAAa;AAAA,IAC3C,WAAW;AAAA,IACX,WAAW,gBAAA;AAAA,EAAgB,CAC5B;AACH;AAKA,eAAsB,eACpB,aACA,aACe;AACf,QAAM,KAAK,oBAAA;AAEX,QAAM,UAAU,IAAI,IAAI,uBAAuB,WAAW,GAAG;AAAA,IAC3D,QAAQ;AAAA;AAAA,IACR,WAAW;AAAA,IACX,WAAW,gBAAA;AAAA,EAAgB,CAC5B;AACH;AAKA,eAAsB,aACpB,aACA,aACe;AACf,QAAM,KAAK,oBAAA;AAEX,QAAM,UAAU,IAAI,IAAI,uBAAuB,WAAW,GAAG;AAAA,IAC3D,QAAQ;AAAA,IACR,SAAS,gBAAA;AAAA,IACT,WAAW;AAAA,IACX,WAAW,gBAAA;AAAA,EAAgB,CAC5B;AACH;AASA,eAAsB,eACpB,OACiB;AACjB,QAAM,KAAK,oBAAA;AAEX,QAAM,eAAe;AAAA,IACnB,GAAG;AAAA,IACH,WAAW,gBAAA;AAAA,IACX,WAAW,gBAAA;AAAA,EAAgB;AAG7B,QAAM,SAAS,MAAM;AAAA,IACnB,WAAW,IAAI,oBAAoB;AAAA,IACnC;AAAA,EAAA;AAGF,SAAO,OAAO;AAChB;AAKA,eAAsB,eACpB,YACA,OACe;AACf,QAAM,KAAK,oBAAA;AAEX,QAAM,UAAU,IAAI,IAAI,sBAAsB,UAAU,GAAG;AAAA,IACzD,GAAG;AAAA,IACH,WAAW,gBAAA;AAAA,EAAgB,CAC5B;AACH;AAKA,eAAsB,eAAe,YAAmC;AACtE,QAAM,KAAK,oBAAA;AACX,QAAM,UAAU,IAAI,IAAI,sBAAsB,UAAU,CAAC;AAC3D;AAKA,eAAsB,kBAAmD;AACvE,QAAM,KAAK,oBAAA;AAEX,QAAM,IAAI;AAAA,IACR,WAAW,IAAI,oBAAoB;AAAA,IACnC,QAAQ,QAAQ,KAAK;AAAA,EAAA;AAGvB,QAAM,WAAW,MAAM,QAAQ,CAAC;AAChC,SAAO,SAAS,KAAK,IAAI,CAAC,MAAM,cAAc,EAAE,IAAI,EAAE,KAAA,CAAM,CAAC;AAC/D;AAKA,eAAsB,gBACpB,YACsC;AACtC,QAAM,KAAK,oBAAA;AACX,QAAM,UAAU,MAAM,OAAO,IAAI,IAAI,sBAAsB,UAAU,CAAC;AAEtE,MAAI,CAAC,QAAQ,OAAA,EAAU,QAAO;AAC9B,SAAO,cAAc,QAAQ,IAAI,QAAQ,MAAM;AACjD;AAKA,eAAsB,gCACpB,WACsC;AACtC,QAAM,KAAK,oBAAA;AAEX,QAAM,IAAI;AAAA,IACR,WAAW,IAAI,oBAAoB;AAAA,IACnC,MAAM,aAAa,MAAM,SAAS;AAAA,EAAA;AAGpC,QAAM,WAAW,MAAM,QAAQ,CAAC;AAChC,MAAI,SAAS,MAAO,QAAO;AAE3B,QAAM,UAAU,SAAS,KAAK,CAAC;AAC/B,MAAI,CAAC,QAAS,QAAO;AAErB,SAAO,cAAc,QAAQ,IAAI,QAAQ,MAAM;AACjD;AASA,eAAsB,sBACpB,aACoC;AACpC,QAAM,KAAK,oBAAA;AAGX,QAAM,YAAY,MAAM,iBAAiB,WAAW;AACpD,MAAI,CAAC,UAAW,QAAO;AAGvB,QAAM,cAAc;AAAA,IAClB,WAAW,IAAI,2BAA2B;AAAA,IAC1C,MAAM,eAAe,MAAM,WAAW;AAAA,EAAA;AAGxC,QAAM,iBAAiB,MAAM,QAAQ,WAAW;AAChD,QAAM,SAAS,eAAe,KAAK,IAAI,CAAC,MAAM,EAAE,MAAM;AAGtD,QAAM,cAAc,OAAO,OAAO,CAAC,MAAM,EAAE,WAAW,YAAY,EAAE;AACpE,QAAM,SAAS,OAAO,OAAO,CAAC,MAAM,EAAE,WAAW,OAAO,EAAE;AAC1D,QAAM,aAAa,OAAO,OAAO,CAAC,MAAM,EAAE,WAAW,SAAS,EAAE;AAGhE,QAAM,aAA+C;AAAA,IACnD,KAAK,EAAE,aAAa,GAAG,QAAQ,EAAA;AAAA,IAC/B,SAAS,EAAE,aAAa,GAAG,QAAQ,EAAA;AAAA,IACnC,KAAK,EAAE,aAAa,GAAG,QAAQ,EAAA;AAAA,EAAE;AAGnC,SAAO,QAAQ,CAAC,MAAM;AACpB,UAAM,WAAW,EAAE;AACnB,QAAI,WAAW,QAAQ,GAAG;AACxB,UAAI,EAAE,WAAW,aAAc,YAAW,QAAQ,EAAE;AACpD,UAAI,EAAE,WAAW,QAAS,YAAW,QAAQ,EAAE;AAAA,IACjD;AAAA,EACF,CAAC;AAGD,QAAM,YAA6C,CAAA;AACnD,SAAO,QAAQ,CAAC,MAAM;AACpB,UAAM,YAAY,EAAE;AACpB,QAAI,CAAC,UAAU,SAAS,GAAG;AACzB,gBAAU,SAAS,IAAI,EAAE,aAAa,GAAG,QAAQ,EAAA;AAAA,IACnD;AACA,QAAI,EAAE,WAAW,aAAc,WAAU,SAAS,EAAE;AACpD,QAAI,EAAE,WAAW,QAAS,WAAU,SAAS,EAAE;AAAA,EACjD,CAAC;AAGD,QAAM,YAAqE,CAAA;AAC3E,SAAO,QAAQ,CAAC,MAAM;AACpB,UAAM,UAAW,EAAE,UAAwB,OAAA,EAAS,cAAc,MAAM,GAAG,EAAE,CAAC;AAC9E,QAAI,SAAS;AACX,UAAI,CAAC,UAAU,OAAO,GAAG;AACvB,kBAAU,OAAO,IAAI,EAAE,aAAa,GAAG,QAAQ,EAAA;AAAA,MACjD;AACA,UAAI,EAAE,WAAW,aAAc,WAAU,OAAO,EAAE;AAClD,UAAI,EAAE,WAAW,QAAS,WAAU,OAAO,EAAE;AAAA,IAC/C;AAAA,EACF,CAAC;AAED,QAAM,SAAS,OAAO,QAAQ,SAAS,EAAE,IAAI,CAAC,CAAC,MAAM,IAAI,OAAO;AAAA,IAC9D;AAAA,IACA,aAAa,KAAK;AAAA,IAClB,QAAQ,KAAK;AAAA,EAAA,EACb;AAEF,SAAO;AAAA,IACL;AAAA,IACA,OAAO,UAAU;AAAA,IACjB,QAAQ,UAAU;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,IACA,KAAK,cAAc,IAAI,SAAS,cAAc;AAAA,IAC9C;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;AAKA,eAAsB,oBACpB,WACA,SACgC;AAChC,QAAM,KAAK,oBAAA;AAGX,QAAM,cAAc;AAAA,IAClB,WAAW,IAAI,2BAA2B;AAAA,IAC1C,MAAM,aAAa,MAAM,UAAU,SAAS,SAAS,CAAC;AAAA,IACtD,MAAM,aAAa,MAAM,UAAU,SAAS,OAAO,CAAC;AAAA,EAAA;AAGtD,QAAM,iBAAiB,MAAM,QAAQ,WAAW;AAChD,QAAM,SAAS,eAAe,KAAK,IAAI,CAAC,MAAM,EAAE,MAAM;AAGtD,QAAM,YAAY,OAAO,OAAO,CAAC,MAAM,EAAE,WAAW,YAAY,EAAE;AAClE,QAAM,YAAY,OAAO,OAAO,CAAC,MAAM,EAAE,WAAW,YAAY,EAAE;AAClE,QAAM,eAAe,OAAO,OAAO,CAAC,MAAM,EAAE,WAAW,OAAO,EAAE;AAGhE,QAAM,aAAkD;AAAA,IACtD,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,EAAA;AAAA,IACrC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,EAAA;AAAA,IACtC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,EAAA;AAAA,IACvC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,EAAA;AAAA,IACrC,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,EAAA;AAAA,IAC1C,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,EAAA;AAAA,EAAE;AAGzC,QAAM,SAA0C;AAAA,IAC9C,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,EAAA;AAAA,IACnC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,EAAA;AAAA,IACtC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,EAAA;AAAA,IACtC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,EAAA;AAAA,IACpC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,EAAA;AAAA,IACvC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,EAAA;AAAA,IACxC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,EAAA;AAAA,EAAE;AAI/C,QAAM,YAA6E,CAAA;AACnF,SAAO,QAAQ,CAAC,MAAM;AACpB,UAAM,UAAW,EAAE,UAAwB,OAAA,EAAS,cAAc,MAAM,GAAG,EAAE,CAAC;AAC9E,QAAI,SAAS;AACX,UAAI,CAAC,UAAU,OAAO,GAAG;AACvB,kBAAU,OAAO,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,EAAA;AAAA,MACpD;AACA,UAAI,EAAE,WAAW,cAAc;AAC7B,kBAAU,OAAO,EAAE;AACnB,kBAAU,OAAO,EAAE;AAAA,MACrB;AACA,UAAI,EAAE,WAAW,QAAS,WAAU,OAAO,EAAE;AAAA,IAC/C;AAAA,EACF,CAAC;AAED,QAAM,SAAS,OAAO,QAAQ,SAAS,EACpC,IAAI,CAAC,CAAC,MAAM,IAAI,OAAO,EAAE,MAAM,GAAG,KAAA,EAAO,EACzC,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AAE9C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU,YAAY,IAAI,YAAY,YAAY;AAAA,IAClD,WAAW,YAAY,IAAI,eAAe,YAAY;AAAA,IACtD;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;AAMO,MAAM,2BAA2B;AAAA;AAAA,EAEtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGA;AAAA,EACA;AACF;ACzhBA,eAAsB,gBAAgB,MAA0C;AAC9E,MAAI;AACF,UAAM,KAAK,oBAAA;AACX,UAAM,SAAS,IAAI,IAAI,2BAA2B,cAAc,MAAM;AACtE,UAAM,OAAO,QAAQ;AAAA,MACnB,GAAG;AAAA,MACH,WAAW,gBAAA;AAAA,IAAgB,CAC5B;AACD,0BAAA;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,MAAM,sDAAsD,KAAK;AACzE,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,kBAAkB,MAAmD;AACzF,MAAI;AACF,UAAM,KAAK,oBAAA;AACX,UAAM,SAAS,IAAI,IAAI,2BAA2B,cAAc,MAAM;AACtE,UAAM,UAAU,QAAQ;AAAA,MACtB,GAAG;AAAA,MACH,WAAW,gBAAA;AAAA,IAAgB,CAC5B;AACD,0BAAA;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,MAAM,wDAAwD,KAAK;AAC3E,WAAO;AAAA,EACT;AACF;AAQA,eAAsB,kBAAkB,MAA4C;AAClF,MAAI;AACF,UAAM,KAAK,oBAAA;AACX,UAAM,SAAS,IAAI,IAAI,2BAA2B,gBAAgB,MAAM;AACxE,UAAM,OAAO,QAAQ;AAAA,MACnB,GAAG;AAAA,MACH,WAAW,gBAAA;AAAA,IAAgB,CAC5B;AACD,4BAAA;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,MAAM,wDAAwD,KAAK;AAC3E,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,oBAAoB,MAAqD;AAC7F,MAAI;AACF,UAAM,KAAK,oBAAA;AACX,UAAM,SAAS,IAAI,IAAI,2BAA2B,gBAAgB,MAAM;AACxE,UAAM,UAAU,QAAQ;AAAA,MACtB,GAAG;AAAA,MACH,WAAW,gBAAA;AAAA,IAAgB,CAC5B;AACD,4BAAA;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,MAAM,0DAA0D,KAAK;AAC7E,WAAO;AAAA,EACT;AACF;AAQA,eAAsB,gBAAgB,MAA0C;AAC9E,MAAI;AACF,UAAM,KAAK,oBAAA;AACX,UAAM,SAAS,IAAI,IAAI,2BAA2B,cAAc,MAAM;AACtE,UAAM,OAAO,QAAQ;AAAA,MACnB,GAAG;AAAA,MACH,WAAW,gBAAA;AAAA,IAAgB,CAC5B;AACD,0BAAA;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,MAAM,sDAAsD,KAAK;AACzE,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,kBAAkB,MAAmD;AACzF,MAAI;AACF,UAAM,KAAK,oBAAA;AACX,UAAM,SAAS,IAAI,IAAI,2BAA2B,cAAc,MAAM;AACtE,UAAM,UAAU,QAAQ;AAAA,MACtB,GAAG;AAAA,MACH,WAAW,gBAAA;AAAA,IAAgB,CAC5B;AACD,0BAAA;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,MAAM,wDAAwD,KAAK;AAC3E,WAAO;AAAA,EACT;AACF;AAQA,eAAsB,iBAAiB,MAA+C;AACpF,MAAI;AACF,UAAM,KAAK,oBAAA;AACX,UAAM,SAAS,WAAW,IAAI,2BAA2B,YAAY;AACrE,UAAM,SAAS,MAAM,OAAO,QAAQ;AAAA,MAClC,GAAG;AAAA,MACH,WAAW,gBAAA;AAAA,IAAgB,CAC5B;AACD,0BAAA;AACA,WAAO,OAAO;AAAA,EAChB,SAAS,OAAO;AACd,YAAQ,MAAM,uDAAuD,KAAK;AAC1E,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,iBAAiB,IAAY,MAAkD;AACnG,MAAI;AACF,UAAM,KAAK,oBAAA;AACX,UAAM,SAAS,IAAI,IAAI,2BAA2B,cAAc,EAAE;AAClE,UAAM,UAAU,QAAQ;AAAA,MACtB,GAAG;AAAA,MACH,WAAW,gBAAA;AAAA,IAAgB,CAC5B;AACD,0BAAA;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,MAAM,uDAAuD,KAAK;AAC1E,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,iBAAiB,IAA8B;AACnE,MAAI;AACF,UAAM,KAAK,oBAAA;AACX,UAAM,SAAS,IAAI,IAAI,2BAA2B,cAAc,EAAE;AAClE,UAAM,UAAU,MAAM;AACtB,0BAAA;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,MAAM,uDAAuD,KAAK;AAC1E,WAAO;AAAA,EACT;AACF;AAQA,eAAsB,oBAAoB,MAAkD;AAC1F,MAAI;AACF,UAAM,KAAK,oBAAA;AACX,UAAM,SAAS,WAAW,IAAI,2BAA2B,eAAe;AACxE,UAAM,SAAS,MAAM,OAAO,QAAQ;AAAA,MAClC,GAAG;AAAA,MACH,WAAW,gBAAA;AAAA,IAAgB,CAC5B;AACD,6BAAA;AACA,WAAO,OAAO;AAAA,EAChB,SAAS,OAAO;AACd,YAAQ,MAAM,0DAA0D,KAAK;AAC7E,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,oBAAoB,IAAY,MAAqD;AACzG,MAAI;AACF,UAAM,KAAK,oBAAA;AACX,UAAM,SAAS,IAAI,IAAI,2BAA2B,iBAAiB,EAAE;AACrE,UAAM,UAAU,QAAQ;AAAA,MACtB,GAAG;AAAA,MACH,WAAW,gBAAA;AAAA,IAAgB,CAC5B;AACD,6BAAA;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,MAAM,0DAA0D,KAAK;AAC7E,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,oBAAoB,IAA8B;AACtE,MAAI;AACF,UAAM,KAAK,oBAAA;AACX,UAAM,SAAS,IAAI,IAAI,2BAA2B,iBAAiB,EAAE;AACrE,UAAM,UAAU,MAAM;AACtB,6BAAA;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,MAAM,0DAA0D,KAAK;AAC7E,WAAO;AAAA,EACT;AACF;AAQA,eAAsB,cAAc,MAA4C;AAC9E,MAAI;AACF,UAAM,KAAK,oBAAA;AACX,UAAM,SAAS,WAAW,IAAI,2BAA2B,QAAQ;AACjE,UAAM,SAAS,MAAM,OAAO,QAAQ;AAAA,MAClC,GAAG;AAAA,MACH,WAAW,gBAAA;AAAA,IAAgB,CAC5B;AACD,uBAAA;AACA,WAAO,OAAO;AAAA,EAChB,SAAS,OAAO;AACd,YAAQ,MAAM,mDAAmD,KAAK;AACtE,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,cAAc,IAAY,MAA+C;AAC7F,MAAI;AACF,UAAM,KAAK,oBAAA;AACX,UAAM,SAAS,IAAI,IAAI,2BAA2B,UAAU,EAAE;AAC9D,UAAM,UAAU,QAAQ;AAAA,MACtB,GAAG;AAAA,MACH,WAAW,gBAAA;AAAA,IAAgB,CAC5B;AACD,uBAAA;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,MAAM,mDAAmD,KAAK;AACtE,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,cAAc,IAA8B;AAChE,MAAI;AACF,UAAM,KAAK,oBAAA;AACX,UAAM,SAAS,IAAI,IAAI,2BAA2B,UAAU,EAAE;AAC9D,UAAM,UAAU,MAAM;AACtB,uBAAA;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,MAAM,mDAAmD,KAAK;AACtE,WAAO;AAAA,EACT;AACF;AAQA,eAAsB,YAAY,MAA0C;AAC1E,MAAI;AACF,UAAM,KAAK,oBAAA;AACX,UAAM,SAAS,WAAW,IAAI,2BAA2B,MAAM;AAC/D,UAAM,SAAS,MAAM,OAAO,QAAQ;AAAA,MAClC,GAAG;AAAA,MACH,WAAW,gBAAA;AAAA,IAAgB,CAC5B;AACD,qBAAA;AACA,WAAO,OAAO;AAAA,EAChB,SAAS,OAAO;AACd,YAAQ,MAAM,iDAAiD,KAAK;AACpE,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,YAAY,IAAY,MAA6C;AACzF,MAAI;AACF,UAAM,KAAK,oBAAA;AACX,UAAM,SAAS,IAAI,IAAI,2BAA2B,QAAQ,EAAE;AAC5D,UAAM,UAAU,QAAQ;AAAA,MACtB,GAAG;AAAA,MACH,WAAW,gBAAA;AAAA,IAAgB,CAC5B;AACD,qBAAA;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,MAAM,iDAAiD,KAAK;AACpE,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,YAAY,IAA8B;AAC9D,MAAI;AACF,UAAM,KAAK,oBAAA;AACX,UAAM,SAAS,IAAI,IAAI,2BAA2B,QAAQ,EAAE;AAC5D,UAAM,UAAU,MAAM;AACtB,qBAAA;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,MAAM,iDAAiD,KAAK;AACpE,WAAO;AAAA,EACT;AACF;AAQA,eAAsB,kBAAkB,MAAgD;AACtF,MAAI;AACF,UAAM,KAAK,oBAAA;AACX,UAAM,SAAS,WAAW,IAAI,2BAA2B,YAAY;AACrE,UAAM,SAAS,MAAM,OAAO,QAAQ;AAAA,MAClC,GAAG;AAAA,MACH,WAAW,gBAAA;AAAA,IAAgB,CAC5B;AACD,2BAAA;AACA,WAAO,OAAO;AAAA,EAChB,SAAS,OAAO;AACd,YAAQ,MAAM,uDAAuD,KAAK;AAC1E,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,kBAAkB,IAAY,MAAmD;AACrG,MAAI;AACF,UAAM,KAAK,oBAAA;AACX,UAAM,SAAS,IAAI,IAAI,2BAA2B,cAAc,EAAE;AAClE,UAAM,UAAU,QAAQ;AAAA,MACtB,GAAG;AAAA,MACH,WAAW,gBAAA;AAAA,IAAgB,CAC5B;AACD,2BAAA;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,MAAM,uDAAuD,KAAK;AAC1E,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,kBAAkB,IAA8B;AACpE,MAAI;AACF,UAAM,KAAK,oBAAA;AACX,UAAM,SAAS,IAAI,IAAI,2BAA2B,cAAc,EAAE;AAClE,UAAM,UAAU,MAAM;AACtB,2BAAA;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,MAAM,uDAAuD,KAAK;AAC1E,WAAO;AAAA,EACT;AACF;AAQA,eAAsB,cAAc,MAA4C;AAC9E,MAAI;AACF,UAAM,KAAK,oBAAA;AACX,UAAM,SAAS,WAAW,IAAI,2BAA2B,QAAQ;AACjE,UAAM,SAAS,MAAM,OAAO,QAAQ;AAAA,MAClC,GAAG;AAAA,MACH,WAAW,gBAAA;AAAA,IAAgB,CAC5B;AACD,uBAAA;AACA,WAAO,OAAO;AAAA,EAChB,SAAS,OAAO;AACd,YAAQ,MAAM,mDAAmD,KAAK;AACtE,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,cAAc,IAAY,MAA+C;AAC7F,MAAI;AACF,UAAM,KAAK,oBAAA;AACX,UAAM,SAAS,IAAI,IAAI,2BAA2B,UAAU,EAAE;AAC9D,UAAM,UAAU,QAAQ;AAAA,MACtB,GAAG;AAAA,MACH,WAAW,gBAAA;AAAA,IAAgB,CAC5B;AACD,uBAAA;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,MAAM,mDAAmD,KAAK;AACtE,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,cAAc,IAA8B;AAChE,MAAI;AACF,UAAM,KAAK,oBAAA;AACX,UAAM,SAAS,IAAI,IAAI,2BAA2B,UAAU,EAAE;AAC9D,UAAM,UAAU,MAAM;AACtB,uBAAA;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,MAAM,mDAAmD,KAAK;AACtE,WAAO;AAAA,EACT;AACF;"}
1
+ {"version":3,"file":"admin-commonFeatures-BKjytwx5.js","sources":["../src/services/admin-notifications.ts","../src/services/admin-commonFeatures.ts"],"sourcesContent":["/**\n * Admin Notifications Service\n *\n * Service for managing broadcasts and templates from the admin panel.\n * Used in aoneahsan.com admin panel to manage cross-project notifications.\n *\n * @author Ahsan Mahmood <aoneahsan@gmail.com>\n */\n\nimport {\n collection,\n doc,\n getDocs,\n getDoc,\n updateDoc,\n deleteDoc,\n addDoc,\n query,\n where,\n orderBy,\n serverTimestamp,\n Timestamp,\n} from 'firebase/firestore';\nimport { getSharedFeaturesDb } from '../firebase/init';\nimport type {\n BroadcastNotification,\n BroadcastStatus,\n CreateBroadcastInput,\n UpdateBroadcastInput,\n NotificationTemplate,\n CreateTemplateInput,\n BroadcastAnalytics,\n NotificationAnalytics,\n} from '../types/notifications';\n\n// ============================================================================\n// CONSTANTS\n// ============================================================================\n\nconst COLLECTION_BROADCASTS = 'zaions_broadcasts';\nconst COLLECTION_TEMPLATES = 'zaions_notification_templates';\nconst COLLECTION_BROADCAST_EVENTS = 'zaions_broadcast_events';\n\n// ============================================================================\n// HELPER FUNCTIONS\n// ============================================================================\n\n/**\n * Convert Firestore document to BroadcastNotification\n */\nfunction docToBroadcast(\n docId: string,\n data: Record<string, unknown>\n): BroadcastNotification {\n return {\n id: docId,\n title: data.title as string,\n message: data.message as string,\n type: data.type as BroadcastNotification['type'],\n category: data.category as BroadcastNotification['category'],\n isRead: false,\n isImportant: data.isImportant as boolean | undefined,\n actionUrl: data.actionUrl as string | undefined,\n actionText: data.actionText as string | undefined,\n createdAt: data.createdAt as Timestamp,\n metadata: data.metadata as Record<string, unknown> | undefined,\n targetProjects: (data.targetProjects as string[]) || [],\n targetPlatforms: (data.targetPlatforms as BroadcastNotification['targetPlatforms']) || [],\n targetAudience: (data.targetAudience as BroadcastNotification['targetAudience']) || 'all',\n status: data.status as BroadcastStatus,\n startDate: data.startDate as Timestamp,\n endDate: data.endDate as Timestamp | null | undefined,\n priority: (data.priority as number) || 50,\n dismissible: data.dismissible !== false,\n variant: (data.variant as BroadcastNotification['variant']) || 'banner',\n impressions: (data.impressions as number) || 0,\n clicks: (data.clicks as number) || 0,\n createdBy: data.createdBy as string,\n updatedBy: data.updatedBy as string | undefined,\n };\n}\n\n/**\n * Convert Firestore document to NotificationTemplate\n */\nfunction docToTemplate(\n docId: string,\n data: Record<string, unknown>\n): NotificationTemplate {\n return {\n id: docId,\n name: data.name as string,\n eventType: data.eventType as string,\n category: data.category as NotificationTemplate['category'],\n title: data.title as string,\n message: data.message as string,\n variables: (data.variables as string[]) || [],\n type: data.type as NotificationTemplate['type'],\n isImportant: data.isImportant as boolean,\n actionUrl: data.actionUrl as string | undefined,\n actionText: data.actionText as string | undefined,\n enabled: data.enabled !== false,\n createdAt: (data.createdAt as Timestamp)?.toDate() || new Date(),\n updatedAt: (data.updatedAt as Timestamp)?.toDate() || new Date(),\n };\n}\n\n// ============================================================================\n// BROADCAST CRUD\n// ============================================================================\n\n/**\n * Create a new broadcast\n */\nexport async function createBroadcast(\n input: CreateBroadcastInput,\n adminUserId: string\n): Promise<string> {\n const db = getSharedFeaturesDb();\n\n const broadcastData = {\n ...input,\n status: 'draft' as BroadcastStatus,\n isRead: false,\n impressions: 0,\n clicks: 0,\n createdBy: adminUserId,\n createdAt: serverTimestamp(),\n startDate: Timestamp.fromDate(input.startDate),\n endDate: input.endDate ? Timestamp.fromDate(input.endDate) : null,\n };\n\n const docRef = await addDoc(\n collection(db, COLLECTION_BROADCASTS),\n broadcastData\n );\n\n return docRef.id;\n}\n\n/**\n * Update an existing broadcast\n */\nexport async function updateBroadcast(\n input: UpdateBroadcastInput,\n adminUserId: string\n): Promise<void> {\n const db = getSharedFeaturesDb();\n\n const updateData: Record<string, unknown> = {\n ...input,\n updatedBy: adminUserId,\n updatedAt: serverTimestamp(),\n };\n\n // Convert dates if provided\n if (input.startDate) {\n updateData.startDate = Timestamp.fromDate(input.startDate);\n }\n if (input.endDate !== undefined) {\n updateData.endDate = input.endDate ? Timestamp.fromDate(input.endDate) : null;\n }\n\n // Remove id from update data\n delete updateData.id;\n\n await updateDoc(doc(db, COLLECTION_BROADCASTS, input.id), updateData);\n}\n\n/**\n * Delete a broadcast\n */\nexport async function deleteBroadcast(broadcastId: string): Promise<void> {\n const db = getSharedFeaturesDb();\n await deleteDoc(doc(db, COLLECTION_BROADCASTS, broadcastId));\n}\n\n/**\n * Get all broadcasts (for admin listing)\n */\nexport async function getAllBroadcasts(): Promise<BroadcastNotification[]> {\n const db = getSharedFeaturesDb();\n\n const q = query(\n collection(db, COLLECTION_BROADCASTS),\n orderBy('createdAt', 'desc')\n );\n\n const snapshot = await getDocs(q);\n return snapshot.docs.map((d) => docToBroadcast(d.id, d.data()));\n}\n\n/**\n * Get broadcasts by status\n */\nexport async function getBroadcastsByStatus(\n status: BroadcastStatus\n): Promise<BroadcastNotification[]> {\n const db = getSharedFeaturesDb();\n\n const q = query(\n collection(db, COLLECTION_BROADCASTS),\n where('status', '==', status),\n orderBy('createdAt', 'desc')\n );\n\n const snapshot = await getDocs(q);\n return snapshot.docs.map((d) => docToBroadcast(d.id, d.data()));\n}\n\n/**\n * Get a single broadcast by ID\n */\nexport async function getBroadcastById(\n broadcastId: string\n): Promise<BroadcastNotification | null> {\n const db = getSharedFeaturesDb();\n const docSnap = await getDoc(doc(db, COLLECTION_BROADCASTS, broadcastId));\n\n if (!docSnap.exists()) return null;\n return docToBroadcast(docSnap.id, docSnap.data());\n}\n\n// ============================================================================\n// BROADCAST STATUS MANAGEMENT\n// ============================================================================\n\n/**\n * Publish a draft broadcast (set to active)\n */\nexport async function publishBroadcast(\n broadcastId: string,\n adminUserId: string\n): Promise<void> {\n const db = getSharedFeaturesDb();\n\n await updateDoc(doc(db, COLLECTION_BROADCASTS, broadcastId), {\n status: 'active',\n updatedBy: adminUserId,\n updatedAt: serverTimestamp(),\n });\n}\n\n/**\n * Schedule a broadcast for later\n */\nexport async function scheduleBroadcast(\n broadcastId: string,\n scheduledDate: Date,\n adminUserId: string\n): Promise<void> {\n const db = getSharedFeaturesDb();\n\n await updateDoc(doc(db, COLLECTION_BROADCASTS, broadcastId), {\n status: 'scheduled',\n startDate: Timestamp.fromDate(scheduledDate),\n updatedBy: adminUserId,\n updatedAt: serverTimestamp(),\n });\n}\n\n/**\n * Pause an active broadcast\n */\nexport async function pauseBroadcast(\n broadcastId: string,\n adminUserId: string\n): Promise<void> {\n const db = getSharedFeaturesDb();\n\n await updateDoc(doc(db, COLLECTION_BROADCASTS, broadcastId), {\n status: 'draft', // Move back to draft\n updatedBy: adminUserId,\n updatedAt: serverTimestamp(),\n });\n}\n\n/**\n * End a broadcast\n */\nexport async function endBroadcast(\n broadcastId: string,\n adminUserId: string\n): Promise<void> {\n const db = getSharedFeaturesDb();\n\n await updateDoc(doc(db, COLLECTION_BROADCASTS, broadcastId), {\n status: 'ended',\n endDate: serverTimestamp(),\n updatedBy: adminUserId,\n updatedAt: serverTimestamp(),\n });\n}\n\n// ============================================================================\n// TEMPLATE CRUD\n// ============================================================================\n\n/**\n * Create a new template\n */\nexport async function createTemplate(\n input: CreateTemplateInput\n): Promise<string> {\n const db = getSharedFeaturesDb();\n\n const templateData = {\n ...input,\n createdAt: serverTimestamp(),\n updatedAt: serverTimestamp(),\n };\n\n const docRef = await addDoc(\n collection(db, COLLECTION_TEMPLATES),\n templateData\n );\n\n return docRef.id;\n}\n\n/**\n * Update an existing template\n */\nexport async function updateTemplate(\n templateId: string,\n input: Partial<CreateTemplateInput>\n): Promise<void> {\n const db = getSharedFeaturesDb();\n\n await updateDoc(doc(db, COLLECTION_TEMPLATES, templateId), {\n ...input,\n updatedAt: serverTimestamp(),\n });\n}\n\n/**\n * Delete a template\n */\nexport async function deleteTemplate(templateId: string): Promise<void> {\n const db = getSharedFeaturesDb();\n await deleteDoc(doc(db, COLLECTION_TEMPLATES, templateId));\n}\n\n/**\n * Get all templates\n */\nexport async function getAllTemplates(): Promise<NotificationTemplate[]> {\n const db = getSharedFeaturesDb();\n\n const q = query(\n collection(db, COLLECTION_TEMPLATES),\n orderBy('name', 'asc')\n );\n\n const snapshot = await getDocs(q);\n return snapshot.docs.map((d) => docToTemplate(d.id, d.data()));\n}\n\n/**\n * Get template by ID\n */\nexport async function getTemplateById(\n templateId: string\n): Promise<NotificationTemplate | null> {\n const db = getSharedFeaturesDb();\n const docSnap = await getDoc(doc(db, COLLECTION_TEMPLATES, templateId));\n\n if (!docSnap.exists()) return null;\n return docToTemplate(docSnap.id, docSnap.data());\n}\n\n/**\n * Get template by event type from Firestore\n */\nexport async function getFirestoreTemplateByEventType(\n eventType: string\n): Promise<NotificationTemplate | null> {\n const db = getSharedFeaturesDb();\n\n const q = query(\n collection(db, COLLECTION_TEMPLATES),\n where('eventType', '==', eventType)\n );\n\n const snapshot = await getDocs(q);\n if (snapshot.empty) return null;\n\n const docSnap = snapshot.docs[0];\n if (!docSnap) return null;\n\n return docToTemplate(docSnap.id, docSnap.data());\n}\n\n// ============================================================================\n// ANALYTICS\n// ============================================================================\n\n/**\n * Get analytics for a specific broadcast\n */\nexport async function getBroadcastAnalytics(\n broadcastId: string\n): Promise<BroadcastAnalytics | null> {\n const db = getSharedFeaturesDb();\n\n // Get broadcast\n const broadcast = await getBroadcastById(broadcastId);\n if (!broadcast) return null;\n\n // Get events\n const eventsQuery = query(\n collection(db, COLLECTION_BROADCAST_EVENTS),\n where('broadcastId', '==', broadcastId)\n );\n\n const eventsSnapshot = await getDocs(eventsQuery);\n const events = eventsSnapshot.docs.map((d) => d.data());\n\n // Calculate analytics\n const impressions = events.filter((e) => e.action === 'impression').length;\n const clicks = events.filter((e) => e.action === 'click').length;\n const dismissals = events.filter((e) => e.action === 'dismiss').length;\n\n // Group by platform\n const byPlatform: BroadcastAnalytics['byPlatform'] = {\n web: { impressions: 0, clicks: 0 },\n android: { impressions: 0, clicks: 0 },\n ios: { impressions: 0, clicks: 0 },\n };\n\n events.forEach((e) => {\n const platform = e.platform as keyof typeof byPlatform;\n if (byPlatform[platform]) {\n if (e.action === 'impression') byPlatform[platform].impressions++;\n if (e.action === 'click') byPlatform[platform].clicks++;\n }\n });\n\n // Group by project\n const byProject: BroadcastAnalytics['byProject'] = {};\n events.forEach((e) => {\n const projectId = e.projectId as string;\n if (!byProject[projectId]) {\n byProject[projectId] = { impressions: 0, clicks: 0 };\n }\n if (e.action === 'impression') byProject[projectId].impressions++;\n if (e.action === 'click') byProject[projectId].clicks++;\n });\n\n // Group by date\n const byDateMap: Record<string, { impressions: number; clicks: number }> = {};\n events.forEach((e) => {\n const dateStr = (e.timestamp as Timestamp).toDate().toISOString().split('T')[0];\n if (dateStr) {\n if (!byDateMap[dateStr]) {\n byDateMap[dateStr] = { impressions: 0, clicks: 0 };\n }\n if (e.action === 'impression') byDateMap[dateStr].impressions++;\n if (e.action === 'click') byDateMap[dateStr].clicks++;\n }\n });\n\n const byDate = Object.entries(byDateMap).map(([date, data]) => ({\n date,\n impressions: data.impressions,\n clicks: data.clicks,\n }));\n\n return {\n broadcastId,\n title: broadcast.title,\n status: broadcast.status,\n impressions,\n clicks,\n dismissals,\n ctr: impressions > 0 ? clicks / impressions : 0,\n byPlatform,\n byProject,\n byDate,\n };\n}\n\n/**\n * Get overall notification analytics\n */\nexport async function getOverallAnalytics(\n startDate: Date,\n endDate: Date\n): Promise<NotificationAnalytics> {\n const db = getSharedFeaturesDb();\n\n // Get all broadcast events in date range\n const eventsQuery = query(\n collection(db, COLLECTION_BROADCAST_EVENTS),\n where('timestamp', '>=', Timestamp.fromDate(startDate)),\n where('timestamp', '<=', Timestamp.fromDate(endDate))\n );\n\n const eventsSnapshot = await getDocs(eventsQuery);\n const events = eventsSnapshot.docs.map((d) => d.data());\n\n // Calculate totals\n const totalSent = events.filter((e) => e.action === 'impression').length;\n const totalRead = events.filter((e) => e.action === 'impression').length; // Impressions = read for broadcasts\n const totalClicked = events.filter((e) => e.action === 'click').length;\n\n // Initialize category and type breakdowns\n const byCategory: NotificationAnalytics['byCategory'] = {\n system: { sent: 0, read: 0, clicked: 0 },\n account: { sent: 0, read: 0, clicked: 0 },\n activity: { sent: 0, read: 0, clicked: 0 },\n report: { sent: 0, read: 0, clicked: 0 },\n promotional: { sent: 0, read: 0, clicked: 0 },\n social: { sent: 0, read: 0, clicked: 0 },\n };\n\n const byType: NotificationAnalytics['byType'] = {\n info: { sent: 0, read: 0, clicked: 0 },\n success: { sent: 0, read: 0, clicked: 0 },\n warning: { sent: 0, read: 0, clicked: 0 },\n error: { sent: 0, read: 0, clicked: 0 },\n reminder: { sent: 0, read: 0, clicked: 0 },\n milestone: { sent: 0, read: 0, clicked: 0 },\n announcement: { sent: 0, read: 0, clicked: 0 },\n };\n\n // Group by date\n const byDateMap: Record<string, { sent: number; read: number; clicked: number }> = {};\n events.forEach((e) => {\n const dateStr = (e.timestamp as Timestamp).toDate().toISOString().split('T')[0];\n if (dateStr) {\n if (!byDateMap[dateStr]) {\n byDateMap[dateStr] = { sent: 0, read: 0, clicked: 0 };\n }\n if (e.action === 'impression') {\n byDateMap[dateStr].sent++;\n byDateMap[dateStr].read++;\n }\n if (e.action === 'click') byDateMap[dateStr].clicked++;\n }\n });\n\n const byDate = Object.entries(byDateMap)\n .map(([date, data]) => ({ date, ...data }))\n .sort((a, b) => a.date.localeCompare(b.date));\n\n return {\n totalSent,\n totalRead,\n totalClicked,\n readRate: totalSent > 0 ? totalRead / totalSent : 0,\n clickRate: totalSent > 0 ? totalClicked / totalSent : 0,\n byCategory,\n byType,\n byDate,\n };\n}\n\n// ============================================================================\n// EXPORT SERVICE OBJECT\n// ============================================================================\n\nexport const adminNotificationService = {\n // Broadcasts\n createBroadcast,\n updateBroadcast,\n deleteBroadcast,\n getAllBroadcasts,\n getBroadcastsByStatus,\n getBroadcastById,\n publishBroadcast,\n scheduleBroadcast,\n pauseBroadcast,\n endBroadcast,\n\n // Templates\n createTemplate,\n updateTemplate,\n deleteTemplate,\n getAllTemplates,\n getTemplateById,\n getFirestoreTemplateByEventType,\n\n // Analytics\n getBroadcastAnalytics,\n getOverallAnalytics,\n};\n\nexport default adminNotificationService;\n","/**\n * Admin Common Features Service\n *\n * Admin CRUD operations for managing common features data.\n * These functions modify the zaions_* collections in Firestore.\n *\n * @author Ahsan Mahmood <aoneahsan@gmail.com>\n */\n\nimport {\n doc,\n setDoc,\n updateDoc,\n deleteDoc,\n collection,\n addDoc,\n serverTimestamp,\n} from 'firebase/firestore';\nimport { getSharedFeaturesDb } from '../firebase/init';\nimport {\n COMMON_FEATURE_COLLECTIONS,\n type ContactInfo,\n type DeveloperInfo,\n type AddressInfo,\n type SocialLink,\n type PaymentOption,\n type Service,\n type Skill,\n type Testimonial,\n type Project,\n} from '../types/commonFeatures';\nimport {\n clearContactInfoCache,\n clearDeveloperInfoCache,\n clearAddressInfoCache,\n clearSocialLinksCache,\n clearPaymentOptionsCache,\n clearServicesCache,\n clearSkillsCache,\n clearTestimonialsCache,\n clearProjectsCache,\n} from './commonFeatures';\n\n// ============================================================================\n// CONTACT INFO ADMIN\n// ============================================================================\n\nexport type ContactInfoInput = Omit<ContactInfo, 'id' | 'updatedAt'>;\n\nexport async function saveContactInfo(data: ContactInfoInput): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.CONTACT_INFO, 'main');\n await setDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearContactInfoCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error saving contact info:', error);\n return false;\n }\n}\n\nexport async function updateContactInfo(data: Partial<ContactInfoInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.CONTACT_INFO, 'main');\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearContactInfoCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating contact info:', error);\n return false;\n }\n}\n\n// ============================================================================\n// DEVELOPER INFO ADMIN\n// ============================================================================\n\nexport type DeveloperInfoInput = Omit<DeveloperInfo, 'id' | 'updatedAt'>;\n\nexport async function saveDeveloperInfo(data: DeveloperInfoInput): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.DEVELOPER_INFO, 'main');\n await setDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearDeveloperInfoCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error saving developer info:', error);\n return false;\n }\n}\n\nexport async function updateDeveloperInfo(data: Partial<DeveloperInfoInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.DEVELOPER_INFO, 'main');\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearDeveloperInfoCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating developer info:', error);\n return false;\n }\n}\n\n// ============================================================================\n// ADDRESS INFO ADMIN\n// ============================================================================\n\nexport type AddressInfoInput = Omit<AddressInfo, 'id' | 'updatedAt'>;\n\nexport async function saveAddressInfo(data: AddressInfoInput): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.ADDRESS_INFO, 'main');\n await setDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearAddressInfoCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error saving address info:', error);\n return false;\n }\n}\n\nexport async function updateAddressInfo(data: Partial<AddressInfoInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.ADDRESS_INFO, 'main');\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearAddressInfoCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating address info:', error);\n return false;\n }\n}\n\n// ============================================================================\n// SOCIAL LINKS ADMIN\n// ============================================================================\n\nexport type SocialLinkInput = Omit<SocialLink, 'id' | 'updatedAt'>;\n\nexport async function createSocialLink(data: SocialLinkInput): Promise<string | null> {\n try {\n const db = getSharedFeaturesDb();\n const colRef = collection(db, COMMON_FEATURE_COLLECTIONS.SOCIAL_LINKS);\n const docRef = await addDoc(colRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearSocialLinksCache();\n return docRef.id;\n } catch (error) {\n console.error('[shared-features admin] Error creating social link:', error);\n return null;\n }\n}\n\nexport async function updateSocialLink(id: string, data: Partial<SocialLinkInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.SOCIAL_LINKS, id);\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearSocialLinksCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating social link:', error);\n return false;\n }\n}\n\nexport async function deleteSocialLink(id: string): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.SOCIAL_LINKS, id);\n await deleteDoc(docRef);\n clearSocialLinksCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error deleting social link:', error);\n return false;\n }\n}\n\n// ============================================================================\n// PAYMENT OPTIONS ADMIN\n// ============================================================================\n\nexport type PaymentOptionInput = Omit<PaymentOption, 'id' | 'updatedAt'>;\n\nexport async function createPaymentOption(data: PaymentOptionInput): Promise<string | null> {\n try {\n const db = getSharedFeaturesDb();\n const colRef = collection(db, COMMON_FEATURE_COLLECTIONS.PAYMENT_OPTIONS);\n const docRef = await addDoc(colRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearPaymentOptionsCache();\n return docRef.id;\n } catch (error) {\n console.error('[shared-features admin] Error creating payment option:', error);\n return null;\n }\n}\n\nexport async function updatePaymentOption(id: string, data: Partial<PaymentOptionInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.PAYMENT_OPTIONS, id);\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearPaymentOptionsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating payment option:', error);\n return false;\n }\n}\n\nexport async function deletePaymentOption(id: string): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.PAYMENT_OPTIONS, id);\n await deleteDoc(docRef);\n clearPaymentOptionsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error deleting payment option:', error);\n return false;\n }\n}\n\n// ============================================================================\n// SERVICES ADMIN\n// ============================================================================\n\nexport type ServiceInput = Omit<Service, 'id' | 'updatedAt'>;\n\nexport async function createService(data: ServiceInput): Promise<string | null> {\n try {\n const db = getSharedFeaturesDb();\n const colRef = collection(db, COMMON_FEATURE_COLLECTIONS.SERVICES);\n const docRef = await addDoc(colRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearServicesCache();\n return docRef.id;\n } catch (error) {\n console.error('[shared-features admin] Error creating service:', error);\n return null;\n }\n}\n\nexport async function updateService(id: string, data: Partial<ServiceInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.SERVICES, id);\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearServicesCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating service:', error);\n return false;\n }\n}\n\nexport async function deleteService(id: string): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.SERVICES, id);\n await deleteDoc(docRef);\n clearServicesCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error deleting service:', error);\n return false;\n }\n}\n\n// ============================================================================\n// SKILLS ADMIN\n// ============================================================================\n\nexport type SkillInput = Omit<Skill, 'id' | 'updatedAt'>;\n\nexport async function createSkill(data: SkillInput): Promise<string | null> {\n try {\n const db = getSharedFeaturesDb();\n const colRef = collection(db, COMMON_FEATURE_COLLECTIONS.SKILLS);\n const docRef = await addDoc(colRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearSkillsCache();\n return docRef.id;\n } catch (error) {\n console.error('[shared-features admin] Error creating skill:', error);\n return null;\n }\n}\n\nexport async function updateSkill(id: string, data: Partial<SkillInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.SKILLS, id);\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearSkillsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating skill:', error);\n return false;\n }\n}\n\nexport async function deleteSkill(id: string): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.SKILLS, id);\n await deleteDoc(docRef);\n clearSkillsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error deleting skill:', error);\n return false;\n }\n}\n\n// ============================================================================\n// TESTIMONIALS ADMIN\n// ============================================================================\n\nexport type TestimonialInput = Omit<Testimonial, 'id' | 'updatedAt'>;\n\nexport async function createTestimonial(data: TestimonialInput): Promise<string | null> {\n try {\n const db = getSharedFeaturesDb();\n const colRef = collection(db, COMMON_FEATURE_COLLECTIONS.TESTIMONIALS);\n const docRef = await addDoc(colRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearTestimonialsCache();\n return docRef.id;\n } catch (error) {\n console.error('[shared-features admin] Error creating testimonial:', error);\n return null;\n }\n}\n\nexport async function updateTestimonial(id: string, data: Partial<TestimonialInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.TESTIMONIALS, id);\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearTestimonialsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating testimonial:', error);\n return false;\n }\n}\n\nexport async function deleteTestimonial(id: string): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.TESTIMONIALS, id);\n await deleteDoc(docRef);\n clearTestimonialsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error deleting testimonial:', error);\n return false;\n }\n}\n\n// ============================================================================\n// PROJECTS ADMIN\n// ============================================================================\n\nexport type ProjectInput = Omit<Project, 'id' | 'updatedAt'>;\n\nexport async function createProject(data: ProjectInput): Promise<string | null> {\n try {\n const db = getSharedFeaturesDb();\n const colRef = collection(db, COMMON_FEATURE_COLLECTIONS.PROJECTS);\n const docRef = await addDoc(colRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearProjectsCache();\n return docRef.id;\n } catch (error) {\n console.error('[shared-features admin] Error creating project:', error);\n return null;\n }\n}\n\nexport async function updateProject(id: string, data: Partial<ProjectInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.PROJECTS, id);\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearProjectsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating project:', error);\n return false;\n }\n}\n\nexport async function deleteProject(id: string): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.PROJECTS, id);\n await deleteDoc(docRef);\n clearProjectsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error deleting project:', error);\n return false;\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  const firestore = require("firebase/firestore");
3
- const commonFeatures = require("./commonFeatures-CgwtnzBH.cjs");
4
- const featureFlags = require("./featureFlags-CvgDQGL0.cjs");
3
+ const commonFeatures = require("./commonFeatures-DMYLR629.cjs");
4
+ const featureFlags = require("./featureFlags-DOwy_uOj.cjs");
5
5
  const COLLECTION_BROADCASTS = "zaions_broadcasts";
6
6
  const COLLECTION_TEMPLATES = "zaions_notification_templates";
7
7
  const COLLECTION_BROADCAST_EVENTS = "zaions_broadcast_events";
@@ -726,4 +726,4 @@ exports.updateSkill = updateSkill;
726
726
  exports.updateSocialLink = updateSocialLink;
727
727
  exports.updateTemplate = updateTemplate;
728
728
  exports.updateTestimonial = updateTestimonial;
729
- //# sourceMappingURL=admin-commonFeatures-BSLz4WzX.cjs.map
729
+ //# sourceMappingURL=admin-commonFeatures-bjszYcI3.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"admin-commonFeatures-BSLz4WzX.cjs","sources":["../src/services/admin-notifications.ts","../src/services/admin-commonFeatures.ts"],"sourcesContent":["/**\n * Admin Notifications Service\n *\n * Service for managing broadcasts and templates from the admin panel.\n * Used in aoneahsan.com admin panel to manage cross-project notifications.\n *\n * @author Ahsan Mahmood <aoneahsan@gmail.com>\n */\n\nimport {\n collection,\n doc,\n getDocs,\n getDoc,\n updateDoc,\n deleteDoc,\n addDoc,\n query,\n where,\n orderBy,\n serverTimestamp,\n Timestamp,\n} from 'firebase/firestore';\nimport { getSharedFeaturesDb } from '../firebase/init';\nimport type {\n BroadcastNotification,\n BroadcastStatus,\n CreateBroadcastInput,\n UpdateBroadcastInput,\n NotificationTemplate,\n CreateTemplateInput,\n BroadcastAnalytics,\n NotificationAnalytics,\n} from '../types/notifications';\n\n// ============================================================================\n// CONSTANTS\n// ============================================================================\n\nconst COLLECTION_BROADCASTS = 'zaions_broadcasts';\nconst COLLECTION_TEMPLATES = 'zaions_notification_templates';\nconst COLLECTION_BROADCAST_EVENTS = 'zaions_broadcast_events';\n\n// ============================================================================\n// HELPER FUNCTIONS\n// ============================================================================\n\n/**\n * Convert Firestore document to BroadcastNotification\n */\nfunction docToBroadcast(\n docId: string,\n data: Record<string, unknown>\n): BroadcastNotification {\n return {\n id: docId,\n title: data.title as string,\n message: data.message as string,\n type: data.type as BroadcastNotification['type'],\n category: data.category as BroadcastNotification['category'],\n isRead: false,\n isImportant: data.isImportant as boolean | undefined,\n actionUrl: data.actionUrl as string | undefined,\n actionText: data.actionText as string | undefined,\n createdAt: data.createdAt as Timestamp,\n metadata: data.metadata as Record<string, unknown> | undefined,\n targetProjects: (data.targetProjects as string[]) || [],\n targetPlatforms: (data.targetPlatforms as BroadcastNotification['targetPlatforms']) || [],\n targetAudience: (data.targetAudience as BroadcastNotification['targetAudience']) || 'all',\n status: data.status as BroadcastStatus,\n startDate: data.startDate as Timestamp,\n endDate: data.endDate as Timestamp | null | undefined,\n priority: (data.priority as number) || 50,\n dismissible: data.dismissible !== false,\n variant: (data.variant as BroadcastNotification['variant']) || 'banner',\n impressions: (data.impressions as number) || 0,\n clicks: (data.clicks as number) || 0,\n createdBy: data.createdBy as string,\n updatedBy: data.updatedBy as string | undefined,\n };\n}\n\n/**\n * Convert Firestore document to NotificationTemplate\n */\nfunction docToTemplate(\n docId: string,\n data: Record<string, unknown>\n): NotificationTemplate {\n return {\n id: docId,\n name: data.name as string,\n eventType: data.eventType as string,\n category: data.category as NotificationTemplate['category'],\n title: data.title as string,\n message: data.message as string,\n variables: (data.variables as string[]) || [],\n type: data.type as NotificationTemplate['type'],\n isImportant: data.isImportant as boolean,\n actionUrl: data.actionUrl as string | undefined,\n actionText: data.actionText as string | undefined,\n enabled: data.enabled !== false,\n createdAt: (data.createdAt as Timestamp)?.toDate() || new Date(),\n updatedAt: (data.updatedAt as Timestamp)?.toDate() || new Date(),\n };\n}\n\n// ============================================================================\n// BROADCAST CRUD\n// ============================================================================\n\n/**\n * Create a new broadcast\n */\nexport async function createBroadcast(\n input: CreateBroadcastInput,\n adminUserId: string\n): Promise<string> {\n const db = getSharedFeaturesDb();\n\n const broadcastData = {\n ...input,\n status: 'draft' as BroadcastStatus,\n isRead: false,\n impressions: 0,\n clicks: 0,\n createdBy: adminUserId,\n createdAt: serverTimestamp(),\n startDate: Timestamp.fromDate(input.startDate),\n endDate: input.endDate ? Timestamp.fromDate(input.endDate) : null,\n };\n\n const docRef = await addDoc(\n collection(db, COLLECTION_BROADCASTS),\n broadcastData\n );\n\n return docRef.id;\n}\n\n/**\n * Update an existing broadcast\n */\nexport async function updateBroadcast(\n input: UpdateBroadcastInput,\n adminUserId: string\n): Promise<void> {\n const db = getSharedFeaturesDb();\n\n const updateData: Record<string, unknown> = {\n ...input,\n updatedBy: adminUserId,\n updatedAt: serverTimestamp(),\n };\n\n // Convert dates if provided\n if (input.startDate) {\n updateData.startDate = Timestamp.fromDate(input.startDate);\n }\n if (input.endDate !== undefined) {\n updateData.endDate = input.endDate ? Timestamp.fromDate(input.endDate) : null;\n }\n\n // Remove id from update data\n delete updateData.id;\n\n await updateDoc(doc(db, COLLECTION_BROADCASTS, input.id), updateData);\n}\n\n/**\n * Delete a broadcast\n */\nexport async function deleteBroadcast(broadcastId: string): Promise<void> {\n const db = getSharedFeaturesDb();\n await deleteDoc(doc(db, COLLECTION_BROADCASTS, broadcastId));\n}\n\n/**\n * Get all broadcasts (for admin listing)\n */\nexport async function getAllBroadcasts(): Promise<BroadcastNotification[]> {\n const db = getSharedFeaturesDb();\n\n const q = query(\n collection(db, COLLECTION_BROADCASTS),\n orderBy('createdAt', 'desc')\n );\n\n const snapshot = await getDocs(q);\n return snapshot.docs.map((d) => docToBroadcast(d.id, d.data()));\n}\n\n/**\n * Get broadcasts by status\n */\nexport async function getBroadcastsByStatus(\n status: BroadcastStatus\n): Promise<BroadcastNotification[]> {\n const db = getSharedFeaturesDb();\n\n const q = query(\n collection(db, COLLECTION_BROADCASTS),\n where('status', '==', status),\n orderBy('createdAt', 'desc')\n );\n\n const snapshot = await getDocs(q);\n return snapshot.docs.map((d) => docToBroadcast(d.id, d.data()));\n}\n\n/**\n * Get a single broadcast by ID\n */\nexport async function getBroadcastById(\n broadcastId: string\n): Promise<BroadcastNotification | null> {\n const db = getSharedFeaturesDb();\n const docSnap = await getDoc(doc(db, COLLECTION_BROADCASTS, broadcastId));\n\n if (!docSnap.exists()) return null;\n return docToBroadcast(docSnap.id, docSnap.data());\n}\n\n// ============================================================================\n// BROADCAST STATUS MANAGEMENT\n// ============================================================================\n\n/**\n * Publish a draft broadcast (set to active)\n */\nexport async function publishBroadcast(\n broadcastId: string,\n adminUserId: string\n): Promise<void> {\n const db = getSharedFeaturesDb();\n\n await updateDoc(doc(db, COLLECTION_BROADCASTS, broadcastId), {\n status: 'active',\n updatedBy: adminUserId,\n updatedAt: serverTimestamp(),\n });\n}\n\n/**\n * Schedule a broadcast for later\n */\nexport async function scheduleBroadcast(\n broadcastId: string,\n scheduledDate: Date,\n adminUserId: string\n): Promise<void> {\n const db = getSharedFeaturesDb();\n\n await updateDoc(doc(db, COLLECTION_BROADCASTS, broadcastId), {\n status: 'scheduled',\n startDate: Timestamp.fromDate(scheduledDate),\n updatedBy: adminUserId,\n updatedAt: serverTimestamp(),\n });\n}\n\n/**\n * Pause an active broadcast\n */\nexport async function pauseBroadcast(\n broadcastId: string,\n adminUserId: string\n): Promise<void> {\n const db = getSharedFeaturesDb();\n\n await updateDoc(doc(db, COLLECTION_BROADCASTS, broadcastId), {\n status: 'draft', // Move back to draft\n updatedBy: adminUserId,\n updatedAt: serverTimestamp(),\n });\n}\n\n/**\n * End a broadcast\n */\nexport async function endBroadcast(\n broadcastId: string,\n adminUserId: string\n): Promise<void> {\n const db = getSharedFeaturesDb();\n\n await updateDoc(doc(db, COLLECTION_BROADCASTS, broadcastId), {\n status: 'ended',\n endDate: serverTimestamp(),\n updatedBy: adminUserId,\n updatedAt: serverTimestamp(),\n });\n}\n\n// ============================================================================\n// TEMPLATE CRUD\n// ============================================================================\n\n/**\n * Create a new template\n */\nexport async function createTemplate(\n input: CreateTemplateInput\n): Promise<string> {\n const db = getSharedFeaturesDb();\n\n const templateData = {\n ...input,\n createdAt: serverTimestamp(),\n updatedAt: serverTimestamp(),\n };\n\n const docRef = await addDoc(\n collection(db, COLLECTION_TEMPLATES),\n templateData\n );\n\n return docRef.id;\n}\n\n/**\n * Update an existing template\n */\nexport async function updateTemplate(\n templateId: string,\n input: Partial<CreateTemplateInput>\n): Promise<void> {\n const db = getSharedFeaturesDb();\n\n await updateDoc(doc(db, COLLECTION_TEMPLATES, templateId), {\n ...input,\n updatedAt: serverTimestamp(),\n });\n}\n\n/**\n * Delete a template\n */\nexport async function deleteTemplate(templateId: string): Promise<void> {\n const db = getSharedFeaturesDb();\n await deleteDoc(doc(db, COLLECTION_TEMPLATES, templateId));\n}\n\n/**\n * Get all templates\n */\nexport async function getAllTemplates(): Promise<NotificationTemplate[]> {\n const db = getSharedFeaturesDb();\n\n const q = query(\n collection(db, COLLECTION_TEMPLATES),\n orderBy('name', 'asc')\n );\n\n const snapshot = await getDocs(q);\n return snapshot.docs.map((d) => docToTemplate(d.id, d.data()));\n}\n\n/**\n * Get template by ID\n */\nexport async function getTemplateById(\n templateId: string\n): Promise<NotificationTemplate | null> {\n const db = getSharedFeaturesDb();\n const docSnap = await getDoc(doc(db, COLLECTION_TEMPLATES, templateId));\n\n if (!docSnap.exists()) return null;\n return docToTemplate(docSnap.id, docSnap.data());\n}\n\n/**\n * Get template by event type from Firestore\n */\nexport async function getFirestoreTemplateByEventType(\n eventType: string\n): Promise<NotificationTemplate | null> {\n const db = getSharedFeaturesDb();\n\n const q = query(\n collection(db, COLLECTION_TEMPLATES),\n where('eventType', '==', eventType)\n );\n\n const snapshot = await getDocs(q);\n if (snapshot.empty) return null;\n\n const docSnap = snapshot.docs[0];\n if (!docSnap) return null;\n\n return docToTemplate(docSnap.id, docSnap.data());\n}\n\n// ============================================================================\n// ANALYTICS\n// ============================================================================\n\n/**\n * Get analytics for a specific broadcast\n */\nexport async function getBroadcastAnalytics(\n broadcastId: string\n): Promise<BroadcastAnalytics | null> {\n const db = getSharedFeaturesDb();\n\n // Get broadcast\n const broadcast = await getBroadcastById(broadcastId);\n if (!broadcast) return null;\n\n // Get events\n const eventsQuery = query(\n collection(db, COLLECTION_BROADCAST_EVENTS),\n where('broadcastId', '==', broadcastId)\n );\n\n const eventsSnapshot = await getDocs(eventsQuery);\n const events = eventsSnapshot.docs.map((d) => d.data());\n\n // Calculate analytics\n const impressions = events.filter((e) => e.action === 'impression').length;\n const clicks = events.filter((e) => e.action === 'click').length;\n const dismissals = events.filter((e) => e.action === 'dismiss').length;\n\n // Group by platform\n const byPlatform: BroadcastAnalytics['byPlatform'] = {\n web: { impressions: 0, clicks: 0 },\n android: { impressions: 0, clicks: 0 },\n ios: { impressions: 0, clicks: 0 },\n };\n\n events.forEach((e) => {\n const platform = e.platform as keyof typeof byPlatform;\n if (byPlatform[platform]) {\n if (e.action === 'impression') byPlatform[platform].impressions++;\n if (e.action === 'click') byPlatform[platform].clicks++;\n }\n });\n\n // Group by project\n const byProject: BroadcastAnalytics['byProject'] = {};\n events.forEach((e) => {\n const projectId = e.projectId as string;\n if (!byProject[projectId]) {\n byProject[projectId] = { impressions: 0, clicks: 0 };\n }\n if (e.action === 'impression') byProject[projectId].impressions++;\n if (e.action === 'click') byProject[projectId].clicks++;\n });\n\n // Group by date\n const byDateMap: Record<string, { impressions: number; clicks: number }> = {};\n events.forEach((e) => {\n const dateStr = (e.timestamp as Timestamp).toDate().toISOString().split('T')[0];\n if (dateStr) {\n if (!byDateMap[dateStr]) {\n byDateMap[dateStr] = { impressions: 0, clicks: 0 };\n }\n if (e.action === 'impression') byDateMap[dateStr].impressions++;\n if (e.action === 'click') byDateMap[dateStr].clicks++;\n }\n });\n\n const byDate = Object.entries(byDateMap).map(([date, data]) => ({\n date,\n impressions: data.impressions,\n clicks: data.clicks,\n }));\n\n return {\n broadcastId,\n title: broadcast.title,\n status: broadcast.status,\n impressions,\n clicks,\n dismissals,\n ctr: impressions > 0 ? clicks / impressions : 0,\n byPlatform,\n byProject,\n byDate,\n };\n}\n\n/**\n * Get overall notification analytics\n */\nexport async function getOverallAnalytics(\n startDate: Date,\n endDate: Date\n): Promise<NotificationAnalytics> {\n const db = getSharedFeaturesDb();\n\n // Get all broadcast events in date range\n const eventsQuery = query(\n collection(db, COLLECTION_BROADCAST_EVENTS),\n where('timestamp', '>=', Timestamp.fromDate(startDate)),\n where('timestamp', '<=', Timestamp.fromDate(endDate))\n );\n\n const eventsSnapshot = await getDocs(eventsQuery);\n const events = eventsSnapshot.docs.map((d) => d.data());\n\n // Calculate totals\n const totalSent = events.filter((e) => e.action === 'impression').length;\n const totalRead = events.filter((e) => e.action === 'impression').length; // Impressions = read for broadcasts\n const totalClicked = events.filter((e) => e.action === 'click').length;\n\n // Initialize category and type breakdowns\n const byCategory: NotificationAnalytics['byCategory'] = {\n system: { sent: 0, read: 0, clicked: 0 },\n account: { sent: 0, read: 0, clicked: 0 },\n activity: { sent: 0, read: 0, clicked: 0 },\n report: { sent: 0, read: 0, clicked: 0 },\n promotional: { sent: 0, read: 0, clicked: 0 },\n social: { sent: 0, read: 0, clicked: 0 },\n };\n\n const byType: NotificationAnalytics['byType'] = {\n info: { sent: 0, read: 0, clicked: 0 },\n success: { sent: 0, read: 0, clicked: 0 },\n warning: { sent: 0, read: 0, clicked: 0 },\n error: { sent: 0, read: 0, clicked: 0 },\n reminder: { sent: 0, read: 0, clicked: 0 },\n milestone: { sent: 0, read: 0, clicked: 0 },\n announcement: { sent: 0, read: 0, clicked: 0 },\n };\n\n // Group by date\n const byDateMap: Record<string, { sent: number; read: number; clicked: number }> = {};\n events.forEach((e) => {\n const dateStr = (e.timestamp as Timestamp).toDate().toISOString().split('T')[0];\n if (dateStr) {\n if (!byDateMap[dateStr]) {\n byDateMap[dateStr] = { sent: 0, read: 0, clicked: 0 };\n }\n if (e.action === 'impression') {\n byDateMap[dateStr].sent++;\n byDateMap[dateStr].read++;\n }\n if (e.action === 'click') byDateMap[dateStr].clicked++;\n }\n });\n\n const byDate = Object.entries(byDateMap)\n .map(([date, data]) => ({ date, ...data }))\n .sort((a, b) => a.date.localeCompare(b.date));\n\n return {\n totalSent,\n totalRead,\n totalClicked,\n readRate: totalSent > 0 ? totalRead / totalSent : 0,\n clickRate: totalSent > 0 ? totalClicked / totalSent : 0,\n byCategory,\n byType,\n byDate,\n };\n}\n\n// ============================================================================\n// EXPORT SERVICE OBJECT\n// ============================================================================\n\nexport const adminNotificationService = {\n // Broadcasts\n createBroadcast,\n updateBroadcast,\n deleteBroadcast,\n getAllBroadcasts,\n getBroadcastsByStatus,\n getBroadcastById,\n publishBroadcast,\n scheduleBroadcast,\n pauseBroadcast,\n endBroadcast,\n\n // Templates\n createTemplate,\n updateTemplate,\n deleteTemplate,\n getAllTemplates,\n getTemplateById,\n getFirestoreTemplateByEventType,\n\n // Analytics\n getBroadcastAnalytics,\n getOverallAnalytics,\n};\n\nexport default adminNotificationService;\n","/**\n * Admin Common Features Service\n *\n * Admin CRUD operations for managing common features data.\n * These functions modify the zaions_* collections in Firestore.\n *\n * @author Ahsan Mahmood <aoneahsan@gmail.com>\n */\n\nimport {\n doc,\n setDoc,\n updateDoc,\n deleteDoc,\n collection,\n addDoc,\n serverTimestamp,\n} from 'firebase/firestore';\nimport { getSharedFeaturesDb } from '../firebase/init';\nimport {\n COMMON_FEATURE_COLLECTIONS,\n type ContactInfo,\n type DeveloperInfo,\n type AddressInfo,\n type SocialLink,\n type PaymentOption,\n type Service,\n type Skill,\n type Testimonial,\n type Project,\n} from '../types/commonFeatures';\nimport {\n clearContactInfoCache,\n clearDeveloperInfoCache,\n clearAddressInfoCache,\n clearSocialLinksCache,\n clearPaymentOptionsCache,\n clearServicesCache,\n clearSkillsCache,\n clearTestimonialsCache,\n clearProjectsCache,\n} from './commonFeatures';\n\n// ============================================================================\n// CONTACT INFO ADMIN\n// ============================================================================\n\nexport type ContactInfoInput = Omit<ContactInfo, 'id' | 'updatedAt'>;\n\nexport async function saveContactInfo(data: ContactInfoInput): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.CONTACT_INFO, 'main');\n await setDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearContactInfoCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error saving contact info:', error);\n return false;\n }\n}\n\nexport async function updateContactInfo(data: Partial<ContactInfoInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.CONTACT_INFO, 'main');\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearContactInfoCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating contact info:', error);\n return false;\n }\n}\n\n// ============================================================================\n// DEVELOPER INFO ADMIN\n// ============================================================================\n\nexport type DeveloperInfoInput = Omit<DeveloperInfo, 'id' | 'updatedAt'>;\n\nexport async function saveDeveloperInfo(data: DeveloperInfoInput): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.DEVELOPER_INFO, 'main');\n await setDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearDeveloperInfoCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error saving developer info:', error);\n return false;\n }\n}\n\nexport async function updateDeveloperInfo(data: Partial<DeveloperInfoInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.DEVELOPER_INFO, 'main');\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearDeveloperInfoCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating developer info:', error);\n return false;\n }\n}\n\n// ============================================================================\n// ADDRESS INFO ADMIN\n// ============================================================================\n\nexport type AddressInfoInput = Omit<AddressInfo, 'id' | 'updatedAt'>;\n\nexport async function saveAddressInfo(data: AddressInfoInput): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.ADDRESS_INFO, 'main');\n await setDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearAddressInfoCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error saving address info:', error);\n return false;\n }\n}\n\nexport async function updateAddressInfo(data: Partial<AddressInfoInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.ADDRESS_INFO, 'main');\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearAddressInfoCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating address info:', error);\n return false;\n }\n}\n\n// ============================================================================\n// SOCIAL LINKS ADMIN\n// ============================================================================\n\nexport type SocialLinkInput = Omit<SocialLink, 'id' | 'updatedAt'>;\n\nexport async function createSocialLink(data: SocialLinkInput): Promise<string | null> {\n try {\n const db = getSharedFeaturesDb();\n const colRef = collection(db, COMMON_FEATURE_COLLECTIONS.SOCIAL_LINKS);\n const docRef = await addDoc(colRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearSocialLinksCache();\n return docRef.id;\n } catch (error) {\n console.error('[shared-features admin] Error creating social link:', error);\n return null;\n }\n}\n\nexport async function updateSocialLink(id: string, data: Partial<SocialLinkInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.SOCIAL_LINKS, id);\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearSocialLinksCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating social link:', error);\n return false;\n }\n}\n\nexport async function deleteSocialLink(id: string): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.SOCIAL_LINKS, id);\n await deleteDoc(docRef);\n clearSocialLinksCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error deleting social link:', error);\n return false;\n }\n}\n\n// ============================================================================\n// PAYMENT OPTIONS ADMIN\n// ============================================================================\n\nexport type PaymentOptionInput = Omit<PaymentOption, 'id' | 'updatedAt'>;\n\nexport async function createPaymentOption(data: PaymentOptionInput): Promise<string | null> {\n try {\n const db = getSharedFeaturesDb();\n const colRef = collection(db, COMMON_FEATURE_COLLECTIONS.PAYMENT_OPTIONS);\n const docRef = await addDoc(colRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearPaymentOptionsCache();\n return docRef.id;\n } catch (error) {\n console.error('[shared-features admin] Error creating payment option:', error);\n return null;\n }\n}\n\nexport async function updatePaymentOption(id: string, data: Partial<PaymentOptionInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.PAYMENT_OPTIONS, id);\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearPaymentOptionsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating payment option:', error);\n return false;\n }\n}\n\nexport async function deletePaymentOption(id: string): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.PAYMENT_OPTIONS, id);\n await deleteDoc(docRef);\n clearPaymentOptionsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error deleting payment option:', error);\n return false;\n }\n}\n\n// ============================================================================\n// SERVICES ADMIN\n// ============================================================================\n\nexport type ServiceInput = Omit<Service, 'id' | 'updatedAt'>;\n\nexport async function createService(data: ServiceInput): Promise<string | null> {\n try {\n const db = getSharedFeaturesDb();\n const colRef = collection(db, COMMON_FEATURE_COLLECTIONS.SERVICES);\n const docRef = await addDoc(colRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearServicesCache();\n return docRef.id;\n } catch (error) {\n console.error('[shared-features admin] Error creating service:', error);\n return null;\n }\n}\n\nexport async function updateService(id: string, data: Partial<ServiceInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.SERVICES, id);\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearServicesCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating service:', error);\n return false;\n }\n}\n\nexport async function deleteService(id: string): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.SERVICES, id);\n await deleteDoc(docRef);\n clearServicesCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error deleting service:', error);\n return false;\n }\n}\n\n// ============================================================================\n// SKILLS ADMIN\n// ============================================================================\n\nexport type SkillInput = Omit<Skill, 'id' | 'updatedAt'>;\n\nexport async function createSkill(data: SkillInput): Promise<string | null> {\n try {\n const db = getSharedFeaturesDb();\n const colRef = collection(db, COMMON_FEATURE_COLLECTIONS.SKILLS);\n const docRef = await addDoc(colRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearSkillsCache();\n return docRef.id;\n } catch (error) {\n console.error('[shared-features admin] Error creating skill:', error);\n return null;\n }\n}\n\nexport async function updateSkill(id: string, data: Partial<SkillInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.SKILLS, id);\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearSkillsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating skill:', error);\n return false;\n }\n}\n\nexport async function deleteSkill(id: string): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.SKILLS, id);\n await deleteDoc(docRef);\n clearSkillsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error deleting skill:', error);\n return false;\n }\n}\n\n// ============================================================================\n// TESTIMONIALS ADMIN\n// ============================================================================\n\nexport type TestimonialInput = Omit<Testimonial, 'id' | 'updatedAt'>;\n\nexport async function createTestimonial(data: TestimonialInput): Promise<string | null> {\n try {\n const db = getSharedFeaturesDb();\n const colRef = collection(db, COMMON_FEATURE_COLLECTIONS.TESTIMONIALS);\n const docRef = await addDoc(colRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearTestimonialsCache();\n return docRef.id;\n } catch (error) {\n console.error('[shared-features admin] Error creating testimonial:', error);\n return null;\n }\n}\n\nexport async function updateTestimonial(id: string, data: Partial<TestimonialInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.TESTIMONIALS, id);\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearTestimonialsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating testimonial:', error);\n return false;\n }\n}\n\nexport async function deleteTestimonial(id: string): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.TESTIMONIALS, id);\n await deleteDoc(docRef);\n clearTestimonialsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error deleting testimonial:', error);\n return false;\n }\n}\n\n// ============================================================================\n// PROJECTS ADMIN\n// ============================================================================\n\nexport type ProjectInput = Omit<Project, 'id' | 'updatedAt'>;\n\nexport async function createProject(data: ProjectInput): Promise<string | null> {\n try {\n const db = getSharedFeaturesDb();\n const colRef = collection(db, COMMON_FEATURE_COLLECTIONS.PROJECTS);\n const docRef = await addDoc(colRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearProjectsCache();\n return docRef.id;\n } catch (error) {\n console.error('[shared-features admin] Error creating project:', error);\n return null;\n }\n}\n\nexport async function updateProject(id: string, data: Partial<ProjectInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.PROJECTS, id);\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearProjectsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating project:', error);\n return false;\n }\n}\n\nexport async function deleteProject(id: string): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.PROJECTS, id);\n await deleteDoc(docRef);\n clearProjectsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error deleting project:', error);\n return false;\n }\n}\n"],"names":["getSharedFeaturesDb","serverTimestamp","Timestamp","addDoc","collection","updateDoc","doc","deleteDoc","query","orderBy","getDocs","where","getDoc","COMMON_FEATURE_COLLECTIONS","setDoc","clearContactInfoCache","clearDeveloperInfoCache","clearAddressInfoCache","clearSocialLinksCache","clearPaymentOptionsCache","clearServicesCache","clearSkillsCache","clearTestimonialsCache","clearProjectsCache"],"mappings":"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"}
1
+ {"version":3,"file":"admin-commonFeatures-bjszYcI3.cjs","sources":["../src/services/admin-notifications.ts","../src/services/admin-commonFeatures.ts"],"sourcesContent":["/**\n * Admin Notifications Service\n *\n * Service for managing broadcasts and templates from the admin panel.\n * Used in aoneahsan.com admin panel to manage cross-project notifications.\n *\n * @author Ahsan Mahmood <aoneahsan@gmail.com>\n */\n\nimport {\n collection,\n doc,\n getDocs,\n getDoc,\n updateDoc,\n deleteDoc,\n addDoc,\n query,\n where,\n orderBy,\n serverTimestamp,\n Timestamp,\n} from 'firebase/firestore';\nimport { getSharedFeaturesDb } from '../firebase/init';\nimport type {\n BroadcastNotification,\n BroadcastStatus,\n CreateBroadcastInput,\n UpdateBroadcastInput,\n NotificationTemplate,\n CreateTemplateInput,\n BroadcastAnalytics,\n NotificationAnalytics,\n} from '../types/notifications';\n\n// ============================================================================\n// CONSTANTS\n// ============================================================================\n\nconst COLLECTION_BROADCASTS = 'zaions_broadcasts';\nconst COLLECTION_TEMPLATES = 'zaions_notification_templates';\nconst COLLECTION_BROADCAST_EVENTS = 'zaions_broadcast_events';\n\n// ============================================================================\n// HELPER FUNCTIONS\n// ============================================================================\n\n/**\n * Convert Firestore document to BroadcastNotification\n */\nfunction docToBroadcast(\n docId: string,\n data: Record<string, unknown>\n): BroadcastNotification {\n return {\n id: docId,\n title: data.title as string,\n message: data.message as string,\n type: data.type as BroadcastNotification['type'],\n category: data.category as BroadcastNotification['category'],\n isRead: false,\n isImportant: data.isImportant as boolean | undefined,\n actionUrl: data.actionUrl as string | undefined,\n actionText: data.actionText as string | undefined,\n createdAt: data.createdAt as Timestamp,\n metadata: data.metadata as Record<string, unknown> | undefined,\n targetProjects: (data.targetProjects as string[]) || [],\n targetPlatforms: (data.targetPlatforms as BroadcastNotification['targetPlatforms']) || [],\n targetAudience: (data.targetAudience as BroadcastNotification['targetAudience']) || 'all',\n status: data.status as BroadcastStatus,\n startDate: data.startDate as Timestamp,\n endDate: data.endDate as Timestamp | null | undefined,\n priority: (data.priority as number) || 50,\n dismissible: data.dismissible !== false,\n variant: (data.variant as BroadcastNotification['variant']) || 'banner',\n impressions: (data.impressions as number) || 0,\n clicks: (data.clicks as number) || 0,\n createdBy: data.createdBy as string,\n updatedBy: data.updatedBy as string | undefined,\n };\n}\n\n/**\n * Convert Firestore document to NotificationTemplate\n */\nfunction docToTemplate(\n docId: string,\n data: Record<string, unknown>\n): NotificationTemplate {\n return {\n id: docId,\n name: data.name as string,\n eventType: data.eventType as string,\n category: data.category as NotificationTemplate['category'],\n title: data.title as string,\n message: data.message as string,\n variables: (data.variables as string[]) || [],\n type: data.type as NotificationTemplate['type'],\n isImportant: data.isImportant as boolean,\n actionUrl: data.actionUrl as string | undefined,\n actionText: data.actionText as string | undefined,\n enabled: data.enabled !== false,\n createdAt: (data.createdAt as Timestamp)?.toDate() || new Date(),\n updatedAt: (data.updatedAt as Timestamp)?.toDate() || new Date(),\n };\n}\n\n// ============================================================================\n// BROADCAST CRUD\n// ============================================================================\n\n/**\n * Create a new broadcast\n */\nexport async function createBroadcast(\n input: CreateBroadcastInput,\n adminUserId: string\n): Promise<string> {\n const db = getSharedFeaturesDb();\n\n const broadcastData = {\n ...input,\n status: 'draft' as BroadcastStatus,\n isRead: false,\n impressions: 0,\n clicks: 0,\n createdBy: adminUserId,\n createdAt: serverTimestamp(),\n startDate: Timestamp.fromDate(input.startDate),\n endDate: input.endDate ? Timestamp.fromDate(input.endDate) : null,\n };\n\n const docRef = await addDoc(\n collection(db, COLLECTION_BROADCASTS),\n broadcastData\n );\n\n return docRef.id;\n}\n\n/**\n * Update an existing broadcast\n */\nexport async function updateBroadcast(\n input: UpdateBroadcastInput,\n adminUserId: string\n): Promise<void> {\n const db = getSharedFeaturesDb();\n\n const updateData: Record<string, unknown> = {\n ...input,\n updatedBy: adminUserId,\n updatedAt: serverTimestamp(),\n };\n\n // Convert dates if provided\n if (input.startDate) {\n updateData.startDate = Timestamp.fromDate(input.startDate);\n }\n if (input.endDate !== undefined) {\n updateData.endDate = input.endDate ? Timestamp.fromDate(input.endDate) : null;\n }\n\n // Remove id from update data\n delete updateData.id;\n\n await updateDoc(doc(db, COLLECTION_BROADCASTS, input.id), updateData);\n}\n\n/**\n * Delete a broadcast\n */\nexport async function deleteBroadcast(broadcastId: string): Promise<void> {\n const db = getSharedFeaturesDb();\n await deleteDoc(doc(db, COLLECTION_BROADCASTS, broadcastId));\n}\n\n/**\n * Get all broadcasts (for admin listing)\n */\nexport async function getAllBroadcasts(): Promise<BroadcastNotification[]> {\n const db = getSharedFeaturesDb();\n\n const q = query(\n collection(db, COLLECTION_BROADCASTS),\n orderBy('createdAt', 'desc')\n );\n\n const snapshot = await getDocs(q);\n return snapshot.docs.map((d) => docToBroadcast(d.id, d.data()));\n}\n\n/**\n * Get broadcasts by status\n */\nexport async function getBroadcastsByStatus(\n status: BroadcastStatus\n): Promise<BroadcastNotification[]> {\n const db = getSharedFeaturesDb();\n\n const q = query(\n collection(db, COLLECTION_BROADCASTS),\n where('status', '==', status),\n orderBy('createdAt', 'desc')\n );\n\n const snapshot = await getDocs(q);\n return snapshot.docs.map((d) => docToBroadcast(d.id, d.data()));\n}\n\n/**\n * Get a single broadcast by ID\n */\nexport async function getBroadcastById(\n broadcastId: string\n): Promise<BroadcastNotification | null> {\n const db = getSharedFeaturesDb();\n const docSnap = await getDoc(doc(db, COLLECTION_BROADCASTS, broadcastId));\n\n if (!docSnap.exists()) return null;\n return docToBroadcast(docSnap.id, docSnap.data());\n}\n\n// ============================================================================\n// BROADCAST STATUS MANAGEMENT\n// ============================================================================\n\n/**\n * Publish a draft broadcast (set to active)\n */\nexport async function publishBroadcast(\n broadcastId: string,\n adminUserId: string\n): Promise<void> {\n const db = getSharedFeaturesDb();\n\n await updateDoc(doc(db, COLLECTION_BROADCASTS, broadcastId), {\n status: 'active',\n updatedBy: adminUserId,\n updatedAt: serverTimestamp(),\n });\n}\n\n/**\n * Schedule a broadcast for later\n */\nexport async function scheduleBroadcast(\n broadcastId: string,\n scheduledDate: Date,\n adminUserId: string\n): Promise<void> {\n const db = getSharedFeaturesDb();\n\n await updateDoc(doc(db, COLLECTION_BROADCASTS, broadcastId), {\n status: 'scheduled',\n startDate: Timestamp.fromDate(scheduledDate),\n updatedBy: adminUserId,\n updatedAt: serverTimestamp(),\n });\n}\n\n/**\n * Pause an active broadcast\n */\nexport async function pauseBroadcast(\n broadcastId: string,\n adminUserId: string\n): Promise<void> {\n const db = getSharedFeaturesDb();\n\n await updateDoc(doc(db, COLLECTION_BROADCASTS, broadcastId), {\n status: 'draft', // Move back to draft\n updatedBy: adminUserId,\n updatedAt: serverTimestamp(),\n });\n}\n\n/**\n * End a broadcast\n */\nexport async function endBroadcast(\n broadcastId: string,\n adminUserId: string\n): Promise<void> {\n const db = getSharedFeaturesDb();\n\n await updateDoc(doc(db, COLLECTION_BROADCASTS, broadcastId), {\n status: 'ended',\n endDate: serverTimestamp(),\n updatedBy: adminUserId,\n updatedAt: serverTimestamp(),\n });\n}\n\n// ============================================================================\n// TEMPLATE CRUD\n// ============================================================================\n\n/**\n * Create a new template\n */\nexport async function createTemplate(\n input: CreateTemplateInput\n): Promise<string> {\n const db = getSharedFeaturesDb();\n\n const templateData = {\n ...input,\n createdAt: serverTimestamp(),\n updatedAt: serverTimestamp(),\n };\n\n const docRef = await addDoc(\n collection(db, COLLECTION_TEMPLATES),\n templateData\n );\n\n return docRef.id;\n}\n\n/**\n * Update an existing template\n */\nexport async function updateTemplate(\n templateId: string,\n input: Partial<CreateTemplateInput>\n): Promise<void> {\n const db = getSharedFeaturesDb();\n\n await updateDoc(doc(db, COLLECTION_TEMPLATES, templateId), {\n ...input,\n updatedAt: serverTimestamp(),\n });\n}\n\n/**\n * Delete a template\n */\nexport async function deleteTemplate(templateId: string): Promise<void> {\n const db = getSharedFeaturesDb();\n await deleteDoc(doc(db, COLLECTION_TEMPLATES, templateId));\n}\n\n/**\n * Get all templates\n */\nexport async function getAllTemplates(): Promise<NotificationTemplate[]> {\n const db = getSharedFeaturesDb();\n\n const q = query(\n collection(db, COLLECTION_TEMPLATES),\n orderBy('name', 'asc')\n );\n\n const snapshot = await getDocs(q);\n return snapshot.docs.map((d) => docToTemplate(d.id, d.data()));\n}\n\n/**\n * Get template by ID\n */\nexport async function getTemplateById(\n templateId: string\n): Promise<NotificationTemplate | null> {\n const db = getSharedFeaturesDb();\n const docSnap = await getDoc(doc(db, COLLECTION_TEMPLATES, templateId));\n\n if (!docSnap.exists()) return null;\n return docToTemplate(docSnap.id, docSnap.data());\n}\n\n/**\n * Get template by event type from Firestore\n */\nexport async function getFirestoreTemplateByEventType(\n eventType: string\n): Promise<NotificationTemplate | null> {\n const db = getSharedFeaturesDb();\n\n const q = query(\n collection(db, COLLECTION_TEMPLATES),\n where('eventType', '==', eventType)\n );\n\n const snapshot = await getDocs(q);\n if (snapshot.empty) return null;\n\n const docSnap = snapshot.docs[0];\n if (!docSnap) return null;\n\n return docToTemplate(docSnap.id, docSnap.data());\n}\n\n// ============================================================================\n// ANALYTICS\n// ============================================================================\n\n/**\n * Get analytics for a specific broadcast\n */\nexport async function getBroadcastAnalytics(\n broadcastId: string\n): Promise<BroadcastAnalytics | null> {\n const db = getSharedFeaturesDb();\n\n // Get broadcast\n const broadcast = await getBroadcastById(broadcastId);\n if (!broadcast) return null;\n\n // Get events\n const eventsQuery = query(\n collection(db, COLLECTION_BROADCAST_EVENTS),\n where('broadcastId', '==', broadcastId)\n );\n\n const eventsSnapshot = await getDocs(eventsQuery);\n const events = eventsSnapshot.docs.map((d) => d.data());\n\n // Calculate analytics\n const impressions = events.filter((e) => e.action === 'impression').length;\n const clicks = events.filter((e) => e.action === 'click').length;\n const dismissals = events.filter((e) => e.action === 'dismiss').length;\n\n // Group by platform\n const byPlatform: BroadcastAnalytics['byPlatform'] = {\n web: { impressions: 0, clicks: 0 },\n android: { impressions: 0, clicks: 0 },\n ios: { impressions: 0, clicks: 0 },\n };\n\n events.forEach((e) => {\n const platform = e.platform as keyof typeof byPlatform;\n if (byPlatform[platform]) {\n if (e.action === 'impression') byPlatform[platform].impressions++;\n if (e.action === 'click') byPlatform[platform].clicks++;\n }\n });\n\n // Group by project\n const byProject: BroadcastAnalytics['byProject'] = {};\n events.forEach((e) => {\n const projectId = e.projectId as string;\n if (!byProject[projectId]) {\n byProject[projectId] = { impressions: 0, clicks: 0 };\n }\n if (e.action === 'impression') byProject[projectId].impressions++;\n if (e.action === 'click') byProject[projectId].clicks++;\n });\n\n // Group by date\n const byDateMap: Record<string, { impressions: number; clicks: number }> = {};\n events.forEach((e) => {\n const dateStr = (e.timestamp as Timestamp).toDate().toISOString().split('T')[0];\n if (dateStr) {\n if (!byDateMap[dateStr]) {\n byDateMap[dateStr] = { impressions: 0, clicks: 0 };\n }\n if (e.action === 'impression') byDateMap[dateStr].impressions++;\n if (e.action === 'click') byDateMap[dateStr].clicks++;\n }\n });\n\n const byDate = Object.entries(byDateMap).map(([date, data]) => ({\n date,\n impressions: data.impressions,\n clicks: data.clicks,\n }));\n\n return {\n broadcastId,\n title: broadcast.title,\n status: broadcast.status,\n impressions,\n clicks,\n dismissals,\n ctr: impressions > 0 ? clicks / impressions : 0,\n byPlatform,\n byProject,\n byDate,\n };\n}\n\n/**\n * Get overall notification analytics\n */\nexport async function getOverallAnalytics(\n startDate: Date,\n endDate: Date\n): Promise<NotificationAnalytics> {\n const db = getSharedFeaturesDb();\n\n // Get all broadcast events in date range\n const eventsQuery = query(\n collection(db, COLLECTION_BROADCAST_EVENTS),\n where('timestamp', '>=', Timestamp.fromDate(startDate)),\n where('timestamp', '<=', Timestamp.fromDate(endDate))\n );\n\n const eventsSnapshot = await getDocs(eventsQuery);\n const events = eventsSnapshot.docs.map((d) => d.data());\n\n // Calculate totals\n const totalSent = events.filter((e) => e.action === 'impression').length;\n const totalRead = events.filter((e) => e.action === 'impression').length; // Impressions = read for broadcasts\n const totalClicked = events.filter((e) => e.action === 'click').length;\n\n // Initialize category and type breakdowns\n const byCategory: NotificationAnalytics['byCategory'] = {\n system: { sent: 0, read: 0, clicked: 0 },\n account: { sent: 0, read: 0, clicked: 0 },\n activity: { sent: 0, read: 0, clicked: 0 },\n report: { sent: 0, read: 0, clicked: 0 },\n promotional: { sent: 0, read: 0, clicked: 0 },\n social: { sent: 0, read: 0, clicked: 0 },\n };\n\n const byType: NotificationAnalytics['byType'] = {\n info: { sent: 0, read: 0, clicked: 0 },\n success: { sent: 0, read: 0, clicked: 0 },\n warning: { sent: 0, read: 0, clicked: 0 },\n error: { sent: 0, read: 0, clicked: 0 },\n reminder: { sent: 0, read: 0, clicked: 0 },\n milestone: { sent: 0, read: 0, clicked: 0 },\n announcement: { sent: 0, read: 0, clicked: 0 },\n };\n\n // Group by date\n const byDateMap: Record<string, { sent: number; read: number; clicked: number }> = {};\n events.forEach((e) => {\n const dateStr = (e.timestamp as Timestamp).toDate().toISOString().split('T')[0];\n if (dateStr) {\n if (!byDateMap[dateStr]) {\n byDateMap[dateStr] = { sent: 0, read: 0, clicked: 0 };\n }\n if (e.action === 'impression') {\n byDateMap[dateStr].sent++;\n byDateMap[dateStr].read++;\n }\n if (e.action === 'click') byDateMap[dateStr].clicked++;\n }\n });\n\n const byDate = Object.entries(byDateMap)\n .map(([date, data]) => ({ date, ...data }))\n .sort((a, b) => a.date.localeCompare(b.date));\n\n return {\n totalSent,\n totalRead,\n totalClicked,\n readRate: totalSent > 0 ? totalRead / totalSent : 0,\n clickRate: totalSent > 0 ? totalClicked / totalSent : 0,\n byCategory,\n byType,\n byDate,\n };\n}\n\n// ============================================================================\n// EXPORT SERVICE OBJECT\n// ============================================================================\n\nexport const adminNotificationService = {\n // Broadcasts\n createBroadcast,\n updateBroadcast,\n deleteBroadcast,\n getAllBroadcasts,\n getBroadcastsByStatus,\n getBroadcastById,\n publishBroadcast,\n scheduleBroadcast,\n pauseBroadcast,\n endBroadcast,\n\n // Templates\n createTemplate,\n updateTemplate,\n deleteTemplate,\n getAllTemplates,\n getTemplateById,\n getFirestoreTemplateByEventType,\n\n // Analytics\n getBroadcastAnalytics,\n getOverallAnalytics,\n};\n\nexport default adminNotificationService;\n","/**\n * Admin Common Features Service\n *\n * Admin CRUD operations for managing common features data.\n * These functions modify the zaions_* collections in Firestore.\n *\n * @author Ahsan Mahmood <aoneahsan@gmail.com>\n */\n\nimport {\n doc,\n setDoc,\n updateDoc,\n deleteDoc,\n collection,\n addDoc,\n serverTimestamp,\n} from 'firebase/firestore';\nimport { getSharedFeaturesDb } from '../firebase/init';\nimport {\n COMMON_FEATURE_COLLECTIONS,\n type ContactInfo,\n type DeveloperInfo,\n type AddressInfo,\n type SocialLink,\n type PaymentOption,\n type Service,\n type Skill,\n type Testimonial,\n type Project,\n} from '../types/commonFeatures';\nimport {\n clearContactInfoCache,\n clearDeveloperInfoCache,\n clearAddressInfoCache,\n clearSocialLinksCache,\n clearPaymentOptionsCache,\n clearServicesCache,\n clearSkillsCache,\n clearTestimonialsCache,\n clearProjectsCache,\n} from './commonFeatures';\n\n// ============================================================================\n// CONTACT INFO ADMIN\n// ============================================================================\n\nexport type ContactInfoInput = Omit<ContactInfo, 'id' | 'updatedAt'>;\n\nexport async function saveContactInfo(data: ContactInfoInput): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.CONTACT_INFO, 'main');\n await setDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearContactInfoCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error saving contact info:', error);\n return false;\n }\n}\n\nexport async function updateContactInfo(data: Partial<ContactInfoInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.CONTACT_INFO, 'main');\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearContactInfoCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating contact info:', error);\n return false;\n }\n}\n\n// ============================================================================\n// DEVELOPER INFO ADMIN\n// ============================================================================\n\nexport type DeveloperInfoInput = Omit<DeveloperInfo, 'id' | 'updatedAt'>;\n\nexport async function saveDeveloperInfo(data: DeveloperInfoInput): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.DEVELOPER_INFO, 'main');\n await setDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearDeveloperInfoCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error saving developer info:', error);\n return false;\n }\n}\n\nexport async function updateDeveloperInfo(data: Partial<DeveloperInfoInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.DEVELOPER_INFO, 'main');\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearDeveloperInfoCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating developer info:', error);\n return false;\n }\n}\n\n// ============================================================================\n// ADDRESS INFO ADMIN\n// ============================================================================\n\nexport type AddressInfoInput = Omit<AddressInfo, 'id' | 'updatedAt'>;\n\nexport async function saveAddressInfo(data: AddressInfoInput): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.ADDRESS_INFO, 'main');\n await setDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearAddressInfoCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error saving address info:', error);\n return false;\n }\n}\n\nexport async function updateAddressInfo(data: Partial<AddressInfoInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.ADDRESS_INFO, 'main');\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearAddressInfoCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating address info:', error);\n return false;\n }\n}\n\n// ============================================================================\n// SOCIAL LINKS ADMIN\n// ============================================================================\n\nexport type SocialLinkInput = Omit<SocialLink, 'id' | 'updatedAt'>;\n\nexport async function createSocialLink(data: SocialLinkInput): Promise<string | null> {\n try {\n const db = getSharedFeaturesDb();\n const colRef = collection(db, COMMON_FEATURE_COLLECTIONS.SOCIAL_LINKS);\n const docRef = await addDoc(colRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearSocialLinksCache();\n return docRef.id;\n } catch (error) {\n console.error('[shared-features admin] Error creating social link:', error);\n return null;\n }\n}\n\nexport async function updateSocialLink(id: string, data: Partial<SocialLinkInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.SOCIAL_LINKS, id);\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearSocialLinksCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating social link:', error);\n return false;\n }\n}\n\nexport async function deleteSocialLink(id: string): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.SOCIAL_LINKS, id);\n await deleteDoc(docRef);\n clearSocialLinksCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error deleting social link:', error);\n return false;\n }\n}\n\n// ============================================================================\n// PAYMENT OPTIONS ADMIN\n// ============================================================================\n\nexport type PaymentOptionInput = Omit<PaymentOption, 'id' | 'updatedAt'>;\n\nexport async function createPaymentOption(data: PaymentOptionInput): Promise<string | null> {\n try {\n const db = getSharedFeaturesDb();\n const colRef = collection(db, COMMON_FEATURE_COLLECTIONS.PAYMENT_OPTIONS);\n const docRef = await addDoc(colRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearPaymentOptionsCache();\n return docRef.id;\n } catch (error) {\n console.error('[shared-features admin] Error creating payment option:', error);\n return null;\n }\n}\n\nexport async function updatePaymentOption(id: string, data: Partial<PaymentOptionInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.PAYMENT_OPTIONS, id);\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearPaymentOptionsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating payment option:', error);\n return false;\n }\n}\n\nexport async function deletePaymentOption(id: string): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.PAYMENT_OPTIONS, id);\n await deleteDoc(docRef);\n clearPaymentOptionsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error deleting payment option:', error);\n return false;\n }\n}\n\n// ============================================================================\n// SERVICES ADMIN\n// ============================================================================\n\nexport type ServiceInput = Omit<Service, 'id' | 'updatedAt'>;\n\nexport async function createService(data: ServiceInput): Promise<string | null> {\n try {\n const db = getSharedFeaturesDb();\n const colRef = collection(db, COMMON_FEATURE_COLLECTIONS.SERVICES);\n const docRef = await addDoc(colRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearServicesCache();\n return docRef.id;\n } catch (error) {\n console.error('[shared-features admin] Error creating service:', error);\n return null;\n }\n}\n\nexport async function updateService(id: string, data: Partial<ServiceInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.SERVICES, id);\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearServicesCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating service:', error);\n return false;\n }\n}\n\nexport async function deleteService(id: string): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.SERVICES, id);\n await deleteDoc(docRef);\n clearServicesCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error deleting service:', error);\n return false;\n }\n}\n\n// ============================================================================\n// SKILLS ADMIN\n// ============================================================================\n\nexport type SkillInput = Omit<Skill, 'id' | 'updatedAt'>;\n\nexport async function createSkill(data: SkillInput): Promise<string | null> {\n try {\n const db = getSharedFeaturesDb();\n const colRef = collection(db, COMMON_FEATURE_COLLECTIONS.SKILLS);\n const docRef = await addDoc(colRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearSkillsCache();\n return docRef.id;\n } catch (error) {\n console.error('[shared-features admin] Error creating skill:', error);\n return null;\n }\n}\n\nexport async function updateSkill(id: string, data: Partial<SkillInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.SKILLS, id);\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearSkillsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating skill:', error);\n return false;\n }\n}\n\nexport async function deleteSkill(id: string): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.SKILLS, id);\n await deleteDoc(docRef);\n clearSkillsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error deleting skill:', error);\n return false;\n }\n}\n\n// ============================================================================\n// TESTIMONIALS ADMIN\n// ============================================================================\n\nexport type TestimonialInput = Omit<Testimonial, 'id' | 'updatedAt'>;\n\nexport async function createTestimonial(data: TestimonialInput): Promise<string | null> {\n try {\n const db = getSharedFeaturesDb();\n const colRef = collection(db, COMMON_FEATURE_COLLECTIONS.TESTIMONIALS);\n const docRef = await addDoc(colRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearTestimonialsCache();\n return docRef.id;\n } catch (error) {\n console.error('[shared-features admin] Error creating testimonial:', error);\n return null;\n }\n}\n\nexport async function updateTestimonial(id: string, data: Partial<TestimonialInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.TESTIMONIALS, id);\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearTestimonialsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating testimonial:', error);\n return false;\n }\n}\n\nexport async function deleteTestimonial(id: string): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.TESTIMONIALS, id);\n await deleteDoc(docRef);\n clearTestimonialsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error deleting testimonial:', error);\n return false;\n }\n}\n\n// ============================================================================\n// PROJECTS ADMIN\n// ============================================================================\n\nexport type ProjectInput = Omit<Project, 'id' | 'updatedAt'>;\n\nexport async function createProject(data: ProjectInput): Promise<string | null> {\n try {\n const db = getSharedFeaturesDb();\n const colRef = collection(db, COMMON_FEATURE_COLLECTIONS.PROJECTS);\n const docRef = await addDoc(colRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearProjectsCache();\n return docRef.id;\n } catch (error) {\n console.error('[shared-features admin] Error creating project:', error);\n return null;\n }\n}\n\nexport async function updateProject(id: string, data: Partial<ProjectInput>): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.PROJECTS, id);\n await updateDoc(docRef, {\n ...data,\n updatedAt: serverTimestamp(),\n });\n clearProjectsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error updating project:', error);\n return false;\n }\n}\n\nexport async function deleteProject(id: string): Promise<boolean> {\n try {\n const db = getSharedFeaturesDb();\n const docRef = doc(db, COMMON_FEATURE_COLLECTIONS.PROJECTS, id);\n await deleteDoc(docRef);\n clearProjectsCache();\n return true;\n } catch (error) {\n console.error('[shared-features admin] Error deleting project:', error);\n return false;\n }\n}\n"],"names":["getSharedFeaturesDb","serverTimestamp","Timestamp","addDoc","collection","updateDoc","doc","deleteDoc","query","orderBy","getDocs","where","getDoc","COMMON_FEATURE_COLLECTIONS","setDoc","clearContactInfoCache","clearDeveloperInfoCache","clearAddressInfoCache","clearSocialLinksCache","clearPaymentOptionsCache","clearServicesCache","clearSkillsCache","clearTestimonialsCache","clearProjectsCache"],"mappings":"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"}
@@ -22,7 +22,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
22
22
  mod
23
23
  ));
24
24
  const firestore = require("firebase/firestore");
25
- const commonFeatures = require("./commonFeatures-CgwtnzBH.cjs");
25
+ const commonFeatures = require("./commonFeatures-DMYLR629.cjs");
26
26
  const COLLECTION_BROADCASTS = "zaions_broadcasts";
27
27
  const COLLECTION_BROADCAST_EVENTS = "zaions_broadcast_events";
28
28
  const LOCAL_STORAGE_KEY = "shared_features_dismissed_broadcasts";
@@ -275,4 +275,4 @@ exports.subscribeToBroadcasts = subscribeToBroadcasts;
275
275
  exports.trackBroadcastClick = trackBroadcastClick;
276
276
  exports.trackBroadcastDismiss = trackBroadcastDismiss;
277
277
  exports.trackBroadcastImpression = trackBroadcastImpression;
278
- //# sourceMappingURL=broadcasts-EUg3P5xI.cjs.map
278
+ //# sourceMappingURL=broadcasts-BeTm29_q.cjs.map