shared-features 0.0.4 → 0.0.5
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.
- package/dist/{AdBanner-CZz8trdz.cjs → AnnouncementModal-Bqy0pn3V.cjs} +428 -3
- package/dist/AnnouncementModal-Bqy0pn3V.cjs.map +1 -0
- package/dist/{AdBanner-DF1QuMxR.js → AnnouncementModal-sxH4K5gy.js} +430 -5
- package/dist/AnnouncementModal-sxH4K5gy.js.map +1 -0
- package/dist/admin-notifications-D9n9h-eY.cjs +362 -0
- package/dist/admin-notifications-D9n9h-eY.cjs.map +1 -0
- package/dist/admin-notifications-p1dy3zIP.js +363 -0
- package/dist/admin-notifications-p1dy3zIP.js.map +1 -0
- package/dist/{analytics-CdpCtTpu.js → analytics-40-S_fHC.js} +3 -2
- package/dist/{analytics-CdpCtTpu.js.map → analytics-40-S_fHC.js.map} +1 -1
- package/dist/{analytics--ZSO9ova.cjs → analytics-lEzOx2vl.cjs} +2 -1
- package/dist/{analytics--ZSO9ova.cjs.map → analytics-lEzOx2vl.cjs.map} +1 -1
- package/dist/broadcasts-3_WfQMNL.cjs +278 -0
- package/dist/broadcasts-3_WfQMNL.cjs.map +1 -0
- package/dist/broadcasts-DgZUzqMf.js +257 -0
- package/dist/broadcasts-DgZUzqMf.js.map +1 -0
- package/dist/components/index.cjs +23 -20
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +4 -1
- package/dist/components/notifications/AnnouncementModal.d.ts +21 -0
- package/dist/components/notifications/AnnouncementModal.d.ts.map +1 -0
- package/dist/components/notifications/BroadcastBanner.d.ts +55 -0
- package/dist/components/notifications/BroadcastBanner.d.ts.map +1 -0
- package/dist/components/notifications/index.d.ts +11 -0
- package/dist/components/notifications/index.d.ts.map +1 -0
- package/dist/hooks/index.cjs +9 -1
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +9 -1
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/useBroadcasts.d.ts +122 -0
- package/dist/hooks/useBroadcasts.d.ts.map +1 -0
- package/dist/index.cjs +99 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +94 -17
- package/dist/index.js.map +1 -1
- package/dist/notifications/events/index.d.ts +14 -0
- package/dist/notifications/events/index.d.ts.map +1 -0
- package/dist/notifications/events/registry.d.ts +75 -0
- package/dist/notifications/events/registry.d.ts.map +1 -0
- package/dist/notifications/events/templates/engine.d.ts +57 -0
- package/dist/notifications/events/templates/engine.d.ts.map +1 -0
- package/dist/notifications/events/templates/standard.d.ts +20 -0
- package/dist/notifications/events/templates/standard.d.ts.map +1 -0
- package/dist/notifications/events/useNotificationEvents.d.ts +36 -0
- package/dist/notifications/events/useNotificationEvents.d.ts.map +1 -0
- package/dist/notifications/index.cjs +25 -0
- package/dist/notifications/index.cjs.map +1 -0
- package/dist/notifications/index.d.ts +9 -0
- package/dist/notifications/index.d.ts.map +1 -0
- package/dist/notifications/index.js +25 -0
- package/dist/notifications/index.js.map +1 -0
- package/dist/services/admin-notifications.d.ts +95 -0
- package/dist/services/admin-notifications.d.ts.map +1 -0
- package/dist/services/broadcasts.d.ts +55 -0
- package/dist/services/broadcasts.d.ts.map +1 -0
- package/dist/services/index.cjs +34 -1
- package/dist/services/index.cjs.map +1 -1
- package/dist/services/index.d.ts +2 -0
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +35 -2
- package/dist/services/index.js.map +1 -1
- package/dist/types/index.cjs +108 -0
- package/dist/types/index.cjs.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +109 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/notifications.d.ts +634 -0
- package/dist/types/notifications.d.ts.map +1 -0
- package/dist/useBroadcasts-DzpCcbC8.js +161 -0
- package/dist/useBroadcasts-DzpCcbC8.js.map +1 -0
- package/dist/useBroadcasts-FP6ZrcY_.cjs +160 -0
- package/dist/useBroadcasts-FP6ZrcY_.cjs.map +1 -0
- package/dist/{useCampaigns-Dltisb9N.cjs → useCampaigns-BOZ9dDsG.cjs} +2 -2
- package/dist/{useCampaigns-Dltisb9N.cjs.map → useCampaigns-BOZ9dDsG.cjs.map} +1 -1
- package/dist/{useCampaigns-nwfsALsN.js → useCampaigns-D46b9zuf.js} +2 -2
- package/dist/{useCampaigns-nwfsALsN.js.map → useCampaigns-D46b9zuf.js.map} +1 -1
- package/dist/useNotificationEvents-BXeMqdak.cjs +954 -0
- package/dist/useNotificationEvents-BXeMqdak.cjs.map +1 -0
- package/dist/useNotificationEvents-D8DVxah1.js +955 -0
- package/dist/useNotificationEvents-D8DVxah1.js.map +1 -0
- package/package.json +11 -3
- package/dist/AdBanner-CZz8trdz.cjs.map +0 -1
- package/dist/AdBanner-DF1QuMxR.js.map +0 -1
package/dist/types/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../src/types/campaigns.ts"],"sourcesContent":["/**\n * Campaign/Advertising System Type Definitions\n *\n * Type definitions for the centralized advertising system including\n * Firestore document schemas, service interfaces, and UI types.\n *\n * Based on ZTools advertising system, adapted for cross-project use.\n *\n * @author Ahsan Mahmood <aoneahsan@gmail.com>\n */\n\nimport { Timestamp } from 'firebase/firestore';\n\n// ============================================================================\n// PRODUCT TYPES\n// ============================================================================\n\n/**\n * Product type classification\n */\nexport type ProductType = 'extension' | 'android' | 'ios' | 'web';\n\n/**\n * Product information for advertising\n */\nexport interface Product {\n /** Unique product identifier */\n id: string;\n /** Product display name */\n name: string;\n /** Short tagline (marketing slogan) */\n tagline: string;\n /** Longer description of the product */\n description: string;\n /** Product type classification */\n type: ProductType;\n /** URL to the product (store link or website) */\n url: string;\n /** Brand/theme color (hex) */\n color: string;\n /** Key features list (3-4 items) */\n features: string[];\n /** Inline SVG icon (64px) */\n icon64?: string;\n /** Inline SVG icon (128px) */\n icon128?: string;\n /** Chrome Web Store URL */\n chromeStoreUrl?: string;\n /** Google Play Store URL */\n playStoreUrl?: string;\n /** Apple App Store URL */\n appStoreUrl?: string;\n /** Web app URL */\n webUrl?: string;\n /** Whether the product is active */\n enabled: boolean;\n /** When the product was created */\n createdAt: Timestamp;\n /** When the product was last updated */\n updatedAt: Timestamp;\n}\n\n// ============================================================================\n// CAMPAIGN TYPES\n// ============================================================================\n\n/**\n * Campaign status values\n */\nexport type CampaignStatus = 'active' | 'paused' | 'scheduled' | 'ended';\n\n/**\n * Target platforms for campaigns\n */\nexport type TargetPlatform = 'web' | 'android' | 'ios' | 'extension';\n\n/**\n * Target audience for campaigns\n */\nexport type TargetAudience = 'all' | 'authenticated' | 'anonymous';\n\n/**\n * Placement options for ads\n */\nexport type AdPlacement =\n | 'popup_slider'\n | 'options_panel'\n | 'onetime_modal'\n | 'update_modal'\n | 'notification'\n | 'footer_slider'\n | 'sidebar_panel'\n | 'home_banner';\n\n/**\n * Small panel variant styles\n */\nexport type SmallPanelVariant =\n | 'small_panel_1' // Minimal\n | 'small_panel_2' // Tagline\n | 'small_panel_3' // Features\n | 'small_panel_4' // Gradient\n | 'small_panel_5'; // Card\n\n/**\n * Large slider variant styles\n */\nexport type LargePanelVariant =\n | 'large_slider_1' // Hero\n | 'large_slider_2' // Feature Grid\n | 'large_slider_3' // Testimonial\n | 'large_slider_4' // Comparison\n | 'large_slider_5'; // Video Placeholder\n\n/**\n * All ad variant types\n */\nexport type AdVariant = SmallPanelVariant | LargePanelVariant;\n\n/**\n * Advertising campaign document\n * Stored in: zaions_campaigns/{campaignId}\n */\nexport interface Campaign {\n /** Campaign document ID */\n id: string;\n /** Reference to product being promoted */\n productId: string;\n /** Campaign name (admin reference) */\n name: string;\n /** Current campaign status */\n status: CampaignStatus;\n\n // === TARGETING ===\n /** Platforms where this campaign should show */\n targetPlatforms: TargetPlatform[];\n /** Audience type to target */\n targetAudience: TargetAudience;\n /** Specific projects to target (empty = all projects) */\n targetProjects: string[];\n /** Don't show to users already using this product */\n excludeProductUsers: boolean;\n\n // === DISPLAY RULES ===\n /** Where the ad can be displayed */\n placements: AdPlacement[];\n /** Priority (1-100, higher = more important) */\n priority: number;\n /** Days between impressions for same user (default: 20) */\n frequencyDays: number;\n /** Maximum total impressions (null = unlimited) */\n maxImpressions: number | null;\n\n // === TIMELINE ===\n /** Campaign start date */\n startDate: Timestamp;\n /** Campaign end date (null = no end) */\n endDate: Timestamp | null;\n\n // === CREATIVE ===\n /** UI variant to use */\n variant: AdVariant;\n /** Custom title (overrides product name) */\n customTitle?: string;\n /** Custom tagline (overrides product tagline) */\n customTagline?: string;\n /** Custom CTA button text */\n customCta?: string;\n /** Custom CTA button URL (overrides product URL) */\n customCtaUrl?: string;\n /** Custom description (overrides product description) */\n customDescription?: string;\n /** Custom product color for custom products/projects */\n customProductColor?: string;\n /** Custom icon SVG string (for custom products) */\n customIcon?: string;\n /** Custom features list (for custom products) */\n customFeatures?: string[];\n\n // === METRICS (Denormalized) ===\n /** Total number of impressions */\n totalImpressions: number;\n /** Total number of clicks */\n totalClicks: number;\n /** Total number of closes/dismissals */\n totalCloses: number;\n\n // === METADATA ===\n /** When campaign was created */\n createdAt: Timestamp;\n /** When campaign was last updated */\n updatedAt: Timestamp;\n /** Admin user ID who created */\n createdBy: string;\n /** Admin user ID who last updated */\n updatedBy?: string;\n}\n\n/**\n * Input for creating a new campaign\n */\nexport interface CreateCampaignInput {\n productId: string;\n name: string;\n status: CampaignStatus;\n targetPlatforms: TargetPlatform[];\n targetAudience: TargetAudience;\n targetProjects: string[];\n excludeProductUsers: boolean;\n placements: AdPlacement[];\n priority: number;\n frequencyDays: number;\n maxImpressions: number | null;\n startDate: Date;\n endDate: Date | null;\n variant: AdVariant;\n customTitle?: string;\n customTagline?: string;\n customCta?: string;\n customCtaUrl?: string;\n customDescription?: string;\n customProductColor?: string;\n customIcon?: string;\n customFeatures?: string[];\n}\n\n/**\n * Input for updating a campaign\n */\nexport interface UpdateCampaignInput extends Partial<CreateCampaignInput> {\n id: string;\n}\n\n// ============================================================================\n// IMPRESSION TYPES\n// ============================================================================\n\n/**\n * Types of ad interactions\n */\nexport type AdAction = 'impression' | 'click' | 'close' | 'notification_click';\n\n/**\n * Ad impression/interaction event\n * Stored in: zaions_impressions/{impressionId}\n */\nexport interface Impression {\n /** Impression document ID */\n id: string;\n /** Campaign that generated this impression */\n campaignId: string;\n /** Product being advertised */\n productId: string;\n /** Project where impression occurred */\n projectId: string;\n\n /** User ID (null for anonymous) */\n userId: string | null;\n /** Device/browser fingerprint */\n deviceId: string;\n /** Platform where impression occurred */\n platform: TargetPlatform;\n /** Placement where ad was shown */\n placement: AdPlacement;\n\n /** Type of interaction */\n action: AdAction;\n /** When the interaction occurred */\n timestamp: Timestamp;\n\n /** UI variant that was displayed */\n variant: AdVariant;\n /** Session identifier */\n sessionId?: string;\n}\n\n/**\n * Input for recording an impression\n */\nexport interface RecordImpressionInput {\n campaignId: string;\n productId: string;\n placement: AdPlacement;\n action: AdAction;\n variant: AdVariant;\n sessionId?: string;\n}\n\n// ============================================================================\n// AD HISTORY TYPES\n// ============================================================================\n\n/**\n * Local ad history entry (for frequency capping)\n */\nexport interface AdHistoryEntry {\n /** Campaign ID */\n campaignId: string;\n /** Product ID */\n productId: string;\n /** Last seen timestamp (Unix ms) */\n lastSeenAt: number;\n /** Impression count */\n impressionCount: number;\n /** Whether clicked */\n clicked: boolean;\n /** Whether closed */\n closed: boolean;\n /** Next eligible timestamp (Unix ms) */\n nextEligibleAt: number;\n}\n\n// ============================================================================\n// SERVICE TYPES\n// ============================================================================\n\n/**\n * Options for fetching campaigns\n */\nexport interface FetchCampaignsOptions {\n /** Filter by placement */\n placement?: AdPlacement;\n /** Filter by status */\n status?: CampaignStatus;\n /** Filter by product */\n productId?: string;\n /** Maximum results */\n limit?: number;\n}\n\n/**\n * Campaign with resolved product data\n */\nexport interface CampaignWithProduct extends Campaign {\n /** Resolved product information */\n product: Product;\n}\n\n// ============================================================================\n// ANALYTICS TYPES\n// ============================================================================\n\n/**\n * Campaign analytics summary\n */\nexport interface CampaignAnalytics {\n campaignId: string;\n campaignName: string;\n productId: string;\n productName: string;\n\n /** Total impressions */\n impressions: number;\n /** Total clicks */\n clicks: number;\n /** Total closes */\n closes: number;\n /** Click-through rate (clicks/impressions) */\n ctr: number;\n /** Close rate (closes/impressions) */\n closeRate: number;\n\n /** Breakdown by platform */\n byPlatform: Record<TargetPlatform, { impressions: number; clicks: number }>;\n /** Breakdown by placement */\n byPlacement: Record<AdPlacement, { impressions: number; clicks: number }>;\n /** Breakdown by project */\n byProject: Record<string, { impressions: number; clicks: number }>;\n /** Daily breakdown */\n byDate: Array<{\n date: string;\n impressions: number;\n clicks: number;\n closes: number;\n }>;\n}\n\n// ============================================================================\n// COMPONENT PROPS\n// ============================================================================\n\n/**\n * Props for small panel variant components\n */\nexport interface SmallPanelProps {\n /** Campaign with product data */\n campaign: CampaignWithProduct;\n /** Called when user clicks CTA */\n onCTAClick?: () => void;\n /** Called when user closes/dismisses the ad */\n onClose?: () => void;\n}\n\n/**\n * Props for large panel variant components\n */\nexport interface LargePanelProps {\n /** Campaign with product data */\n campaign: CampaignWithProduct;\n /** Called when user clicks CTA */\n onCTAClick?: () => void;\n /** Called when user closes/dismisses the ad */\n onClose?: () => void;\n /** Whether to show slide indicator */\n showIndicator?: boolean;\n /** Current slide index (for carousel) */\n currentIndex?: number;\n /** Total number of slides (for carousel) */\n totalCount?: number;\n}\n\n/**\n * Props for ad panel component\n */\nexport interface AdPanelProps {\n placement: AdPlacement;\n variant?: SmallPanelVariant;\n className?: string;\n}\n\n// ============================================================================\n// DEFAULT VALUES\n// ============================================================================\n\n/**\n * Default frequency cap in days\n */\nexport const DEFAULT_FREQUENCY_DAYS = 20;\n\n/**\n * Default campaign priority\n */\nexport const DEFAULT_CAMPAIGN_PRIORITY = 50;\n\n/**\n * Variant display names\n */\nexport const VARIANT_NAMES: Record<AdVariant, string> = {\n small_panel_1: 'Minimal',\n small_panel_2: 'Tagline',\n small_panel_3: 'Features',\n small_panel_4: 'Gradient',\n small_panel_5: 'Card',\n large_slider_1: 'Hero',\n large_slider_2: 'Feature Grid',\n large_slider_3: 'Testimonial',\n large_slider_4: 'Comparison',\n large_slider_5: 'Video Placeholder',\n};\n\n/**\n * Placement display names\n */\nexport const PLACEMENT_NAMES: Record<AdPlacement, string> = {\n popup_slider: 'Extension Popup Slider',\n options_panel: 'Extension Options Panel',\n onetime_modal: 'One-Time Welcome Modal',\n update_modal: 'Update Announcement Modal',\n notification: 'Browser Notification',\n footer_slider: 'Web App Footer Slider',\n sidebar_panel: 'Web App Sidebar Panel',\n home_banner: 'Home Page Banner',\n};\n\n/**\n * Platform display names\n */\nexport const PLATFORM_NAMES: Record<TargetPlatform, string> = {\n web: 'Web App',\n android: 'Android App',\n ios: 'iOS App',\n extension: 'Browser Extension',\n};\n\n// ============================================================================\n// FIREBASE COLLECTION NAMES\n// ============================================================================\n\n/**\n * Collection names for shared features\n */\nexport const COLLECTIONS = {\n CAMPAIGNS: 'zaions_campaigns',\n PRODUCTS: 'zaions_products',\n IMPRESSIONS: 'zaions_impressions',\n CONTACTS: 'zaions_contacts',\n FEATURE_REQUESTS: 'zaions_feature_requests',\n PAYMENT_OPTIONS: 'zaions_payment_options',\n SOCIAL_LINKS: 'zaions_social_links',\n DEVELOPER_INFO: 'zaions_developer_info',\n} as const;\n"],"names":[],"mappings":";;AA2aO,MAAM,yBAAyB;AAK/B,MAAM,4BAA4B;AAKlC,MAAM,gBAA2C;AAAA,EACtD,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,gBAAgB;AAClB;AAKO,MAAM,kBAA+C;AAAA,EAC1D,cAAc;AAAA,EACd,eAAe;AAAA,EACf,eAAe;AAAA,EACf,cAAc;AAAA,EACd,cAAc;AAAA,EACd,eAAe;AAAA,EACf,eAAe;AAAA,EACf,aAAa;AACf;AAKO,MAAM,iBAAiD;AAAA,EAC5D,KAAK;AAAA,EACL,SAAS;AAAA,EACT,KAAK;AAAA,EACL,WAAW;AACb;AASO,MAAM,cAAc;AAAA,EACzB,WAAW;AAAA,EACX,UAAU;AAAA,EACV,aAAa;AAAA,EACb,UAAU;AAAA,EACV,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,cAAc;AAAA,EACd,gBAAgB;AAClB;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../src/types/campaigns.ts","../../src/types/notifications.ts"],"sourcesContent":["/**\n * Campaign/Advertising System Type Definitions\n *\n * Type definitions for the centralized advertising system including\n * Firestore document schemas, service interfaces, and UI types.\n *\n * Based on ZTools advertising system, adapted for cross-project use.\n *\n * @author Ahsan Mahmood <aoneahsan@gmail.com>\n */\n\nimport { Timestamp } from 'firebase/firestore';\n\n// ============================================================================\n// PRODUCT TYPES\n// ============================================================================\n\n/**\n * Product type classification\n */\nexport type ProductType = 'extension' | 'android' | 'ios' | 'web';\n\n/**\n * Product information for advertising\n */\nexport interface Product {\n /** Unique product identifier */\n id: string;\n /** Product display name */\n name: string;\n /** Short tagline (marketing slogan) */\n tagline: string;\n /** Longer description of the product */\n description: string;\n /** Product type classification */\n type: ProductType;\n /** URL to the product (store link or website) */\n url: string;\n /** Brand/theme color (hex) */\n color: string;\n /** Key features list (3-4 items) */\n features: string[];\n /** Inline SVG icon (64px) */\n icon64?: string;\n /** Inline SVG icon (128px) */\n icon128?: string;\n /** Chrome Web Store URL */\n chromeStoreUrl?: string;\n /** Google Play Store URL */\n playStoreUrl?: string;\n /** Apple App Store URL */\n appStoreUrl?: string;\n /** Web app URL */\n webUrl?: string;\n /** Whether the product is active */\n enabled: boolean;\n /** When the product was created */\n createdAt: Timestamp;\n /** When the product was last updated */\n updatedAt: Timestamp;\n}\n\n// ============================================================================\n// CAMPAIGN TYPES\n// ============================================================================\n\n/**\n * Campaign status values\n */\nexport type CampaignStatus = 'active' | 'paused' | 'scheduled' | 'ended';\n\n/**\n * Target platforms for campaigns\n */\nexport type TargetPlatform = 'web' | 'android' | 'ios' | 'extension';\n\n/**\n * Target audience for campaigns\n */\nexport type TargetAudience = 'all' | 'authenticated' | 'anonymous';\n\n/**\n * Placement options for ads\n */\nexport type AdPlacement =\n | 'popup_slider'\n | 'options_panel'\n | 'onetime_modal'\n | 'update_modal'\n | 'notification'\n | 'footer_slider'\n | 'sidebar_panel'\n | 'home_banner';\n\n/**\n * Small panel variant styles\n */\nexport type SmallPanelVariant =\n | 'small_panel_1' // Minimal\n | 'small_panel_2' // Tagline\n | 'small_panel_3' // Features\n | 'small_panel_4' // Gradient\n | 'small_panel_5'; // Card\n\n/**\n * Large slider variant styles\n */\nexport type LargePanelVariant =\n | 'large_slider_1' // Hero\n | 'large_slider_2' // Feature Grid\n | 'large_slider_3' // Testimonial\n | 'large_slider_4' // Comparison\n | 'large_slider_5'; // Video Placeholder\n\n/**\n * All ad variant types\n */\nexport type AdVariant = SmallPanelVariant | LargePanelVariant;\n\n/**\n * Advertising campaign document\n * Stored in: zaions_campaigns/{campaignId}\n */\nexport interface Campaign {\n /** Campaign document ID */\n id: string;\n /** Reference to product being promoted */\n productId: string;\n /** Campaign name (admin reference) */\n name: string;\n /** Current campaign status */\n status: CampaignStatus;\n\n // === TARGETING ===\n /** Platforms where this campaign should show */\n targetPlatforms: TargetPlatform[];\n /** Audience type to target */\n targetAudience: TargetAudience;\n /** Specific projects to target (empty = all projects) */\n targetProjects: string[];\n /** Don't show to users already using this product */\n excludeProductUsers: boolean;\n\n // === DISPLAY RULES ===\n /** Where the ad can be displayed */\n placements: AdPlacement[];\n /** Priority (1-100, higher = more important) */\n priority: number;\n /** Days between impressions for same user (default: 20) */\n frequencyDays: number;\n /** Maximum total impressions (null = unlimited) */\n maxImpressions: number | null;\n\n // === TIMELINE ===\n /** Campaign start date */\n startDate: Timestamp;\n /** Campaign end date (null = no end) */\n endDate: Timestamp | null;\n\n // === CREATIVE ===\n /** UI variant to use */\n variant: AdVariant;\n /** Custom title (overrides product name) */\n customTitle?: string;\n /** Custom tagline (overrides product tagline) */\n customTagline?: string;\n /** Custom CTA button text */\n customCta?: string;\n /** Custom CTA button URL (overrides product URL) */\n customCtaUrl?: string;\n /** Custom description (overrides product description) */\n customDescription?: string;\n /** Custom product color for custom products/projects */\n customProductColor?: string;\n /** Custom icon SVG string (for custom products) */\n customIcon?: string;\n /** Custom features list (for custom products) */\n customFeatures?: string[];\n\n // === METRICS (Denormalized) ===\n /** Total number of impressions */\n totalImpressions: number;\n /** Total number of clicks */\n totalClicks: number;\n /** Total number of closes/dismissals */\n totalCloses: number;\n\n // === METADATA ===\n /** When campaign was created */\n createdAt: Timestamp;\n /** When campaign was last updated */\n updatedAt: Timestamp;\n /** Admin user ID who created */\n createdBy: string;\n /** Admin user ID who last updated */\n updatedBy?: string;\n}\n\n/**\n * Input for creating a new campaign\n */\nexport interface CreateCampaignInput {\n productId: string;\n name: string;\n status: CampaignStatus;\n targetPlatforms: TargetPlatform[];\n targetAudience: TargetAudience;\n targetProjects: string[];\n excludeProductUsers: boolean;\n placements: AdPlacement[];\n priority: number;\n frequencyDays: number;\n maxImpressions: number | null;\n startDate: Date;\n endDate: Date | null;\n variant: AdVariant;\n customTitle?: string;\n customTagline?: string;\n customCta?: string;\n customCtaUrl?: string;\n customDescription?: string;\n customProductColor?: string;\n customIcon?: string;\n customFeatures?: string[];\n}\n\n/**\n * Input for updating a campaign\n */\nexport interface UpdateCampaignInput extends Partial<CreateCampaignInput> {\n id: string;\n}\n\n// ============================================================================\n// IMPRESSION TYPES\n// ============================================================================\n\n/**\n * Types of ad interactions\n */\nexport type AdAction = 'impression' | 'click' | 'close' | 'notification_click';\n\n/**\n * Ad impression/interaction event\n * Stored in: zaions_impressions/{impressionId}\n */\nexport interface Impression {\n /** Impression document ID */\n id: string;\n /** Campaign that generated this impression */\n campaignId: string;\n /** Product being advertised */\n productId: string;\n /** Project where impression occurred */\n projectId: string;\n\n /** User ID (null for anonymous) */\n userId: string | null;\n /** Device/browser fingerprint */\n deviceId: string;\n /** Platform where impression occurred */\n platform: TargetPlatform;\n /** Placement where ad was shown */\n placement: AdPlacement;\n\n /** Type of interaction */\n action: AdAction;\n /** When the interaction occurred */\n timestamp: Timestamp;\n\n /** UI variant that was displayed */\n variant: AdVariant;\n /** Session identifier */\n sessionId?: string;\n}\n\n/**\n * Input for recording an impression\n */\nexport interface RecordImpressionInput {\n campaignId: string;\n productId: string;\n placement: AdPlacement;\n action: AdAction;\n variant: AdVariant;\n sessionId?: string;\n}\n\n// ============================================================================\n// AD HISTORY TYPES\n// ============================================================================\n\n/**\n * Local ad history entry (for frequency capping)\n */\nexport interface AdHistoryEntry {\n /** Campaign ID */\n campaignId: string;\n /** Product ID */\n productId: string;\n /** Last seen timestamp (Unix ms) */\n lastSeenAt: number;\n /** Impression count */\n impressionCount: number;\n /** Whether clicked */\n clicked: boolean;\n /** Whether closed */\n closed: boolean;\n /** Next eligible timestamp (Unix ms) */\n nextEligibleAt: number;\n}\n\n// ============================================================================\n// SERVICE TYPES\n// ============================================================================\n\n/**\n * Options for fetching campaigns\n */\nexport interface FetchCampaignsOptions {\n /** Filter by placement */\n placement?: AdPlacement;\n /** Filter by status */\n status?: CampaignStatus;\n /** Filter by product */\n productId?: string;\n /** Maximum results */\n limit?: number;\n}\n\n/**\n * Campaign with resolved product data\n */\nexport interface CampaignWithProduct extends Campaign {\n /** Resolved product information */\n product: Product;\n}\n\n// ============================================================================\n// ANALYTICS TYPES\n// ============================================================================\n\n/**\n * Campaign analytics summary\n */\nexport interface CampaignAnalytics {\n campaignId: string;\n campaignName: string;\n productId: string;\n productName: string;\n\n /** Total impressions */\n impressions: number;\n /** Total clicks */\n clicks: number;\n /** Total closes */\n closes: number;\n /** Click-through rate (clicks/impressions) */\n ctr: number;\n /** Close rate (closes/impressions) */\n closeRate: number;\n\n /** Breakdown by platform */\n byPlatform: Record<TargetPlatform, { impressions: number; clicks: number }>;\n /** Breakdown by placement */\n byPlacement: Record<AdPlacement, { impressions: number; clicks: number }>;\n /** Breakdown by project */\n byProject: Record<string, { impressions: number; clicks: number }>;\n /** Daily breakdown */\n byDate: Array<{\n date: string;\n impressions: number;\n clicks: number;\n closes: number;\n }>;\n}\n\n// ============================================================================\n// COMPONENT PROPS\n// ============================================================================\n\n/**\n * Props for small panel variant components\n */\nexport interface SmallPanelProps {\n /** Campaign with product data */\n campaign: CampaignWithProduct;\n /** Called when user clicks CTA */\n onCTAClick?: () => void;\n /** Called when user closes/dismisses the ad */\n onClose?: () => void;\n}\n\n/**\n * Props for large panel variant components\n */\nexport interface LargePanelProps {\n /** Campaign with product data */\n campaign: CampaignWithProduct;\n /** Called when user clicks CTA */\n onCTAClick?: () => void;\n /** Called when user closes/dismisses the ad */\n onClose?: () => void;\n /** Whether to show slide indicator */\n showIndicator?: boolean;\n /** Current slide index (for carousel) */\n currentIndex?: number;\n /** Total number of slides (for carousel) */\n totalCount?: number;\n}\n\n/**\n * Props for ad panel component\n */\nexport interface AdPanelProps {\n placement: AdPlacement;\n variant?: SmallPanelVariant;\n className?: string;\n}\n\n// ============================================================================\n// DEFAULT VALUES\n// ============================================================================\n\n/**\n * Default frequency cap in days\n */\nexport const DEFAULT_FREQUENCY_DAYS = 20;\n\n/**\n * Default campaign priority\n */\nexport const DEFAULT_CAMPAIGN_PRIORITY = 50;\n\n/**\n * Variant display names\n */\nexport const VARIANT_NAMES: Record<AdVariant, string> = {\n small_panel_1: 'Minimal',\n small_panel_2: 'Tagline',\n small_panel_3: 'Features',\n small_panel_4: 'Gradient',\n small_panel_5: 'Card',\n large_slider_1: 'Hero',\n large_slider_2: 'Feature Grid',\n large_slider_3: 'Testimonial',\n large_slider_4: 'Comparison',\n large_slider_5: 'Video Placeholder',\n};\n\n/**\n * Placement display names\n */\nexport const PLACEMENT_NAMES: Record<AdPlacement, string> = {\n popup_slider: 'Extension Popup Slider',\n options_panel: 'Extension Options Panel',\n onetime_modal: 'One-Time Welcome Modal',\n update_modal: 'Update Announcement Modal',\n notification: 'Browser Notification',\n footer_slider: 'Web App Footer Slider',\n sidebar_panel: 'Web App Sidebar Panel',\n home_banner: 'Home Page Banner',\n};\n\n/**\n * Platform display names\n */\nexport const PLATFORM_NAMES: Record<TargetPlatform, string> = {\n web: 'Web App',\n android: 'Android App',\n ios: 'iOS App',\n extension: 'Browser Extension',\n};\n\n// ============================================================================\n// FIREBASE COLLECTION NAMES\n// ============================================================================\n\n/**\n * Collection names for shared features\n */\nexport const COLLECTIONS = {\n CAMPAIGNS: 'zaions_campaigns',\n PRODUCTS: 'zaions_products',\n IMPRESSIONS: 'zaions_impressions',\n CONTACTS: 'zaions_contacts',\n FEATURE_REQUESTS: 'zaions_feature_requests',\n PAYMENT_OPTIONS: 'zaions_payment_options',\n SOCIAL_LINKS: 'zaions_social_links',\n DEVELOPER_INFO: 'zaions_developer_info',\n} as const;\n","/**\n * In-App Notification System Type Definitions\n *\n * Type definitions for the unified notification system including\n * broadcasts, user notifications, templates, and preferences.\n *\n * Architecture:\n * - Broadcasts: Stored in shared-features Firebase (zaions_broadcasts)\n * - User notifications: Stored in consumer project's Firebase\n * - Templates: Stored in shared-features Firebase (zaions_notification_templates)\n *\n * @author Ahsan Mahmood <aoneahsan@gmail.com>\n */\n\nimport { Timestamp } from 'firebase/firestore';\n\n// ============================================================================\n// NOTIFICATION CATEGORIES & TYPES\n// ============================================================================\n\n/**\n * Standard notification categories for grouping and filtering\n */\nexport type NotificationCategory =\n | 'system' // Maintenance, updates, outages\n | 'account' // Welcome, security, profile changes\n | 'activity' // CRUD operations, user actions\n | 'report' // Weekly/monthly summaries\n | 'promotional' // Tips, features, holidays\n | 'social'; // Shares, mentions, comments\n\n/**\n * Visual notification type for styling\n */\nexport type NotificationType =\n | 'info' // General information\n | 'success' // Positive feedback\n | 'warning' // Attention needed\n | 'error' // Something went wrong\n | 'reminder' // Time-based reminder\n | 'milestone' // Achievement/progress\n | 'announcement'; // Important announcement\n\n/**\n * Priority levels for notifications\n */\nexport type NotificationPriority = 'urgent' | 'high' | 'normal' | 'low';\n\n/**\n * Source of the notification\n */\nexport type NotificationSource =\n | 'system' // Auto-generated by system\n | 'event' // Triggered by user action\n | 'broadcast' // Cross-project announcement\n | 'admin'; // Sent by admin\n\n/**\n * Broadcast display variants\n */\nexport type BroadcastVariant = 'banner' | 'modal' | 'toast' | 'bell';\n\n/**\n * Broadcast status\n */\nexport type BroadcastStatus = 'draft' | 'scheduled' | 'active' | 'ended';\n\n/**\n * Target platforms for notifications\n */\nexport type NotificationPlatform = 'web' | 'android' | 'ios';\n\n/**\n * Target audience for broadcasts\n */\nexport type NotificationAudience = 'all' | 'authenticated' | 'anonymous';\n\n// ============================================================================\n// STANDARD EVENT TYPES\n// ============================================================================\n\n/**\n * Standard event types that trigger notifications\n */\nexport type StandardEventType =\n // Account Events\n | 'ACCOUNT_CREATED'\n | 'ACCOUNT_WELCOME'\n | 'NEW_DEVICE_SIGNIN'\n | 'PASSWORD_CHANGED'\n | 'PROFILE_UPDATED'\n | 'ACCOUNT_DELETED'\n // Report Events\n | 'DAILY_SUMMARY'\n | 'WEEKLY_SUMMARY'\n | 'MONTHLY_SUMMARY'\n | 'QUARTERLY_SUMMARY'\n | 'YEARLY_SUMMARY'\n // Promotional Events\n | 'APP_TIP'\n | 'HIDDEN_FEATURE'\n | 'NEW_FEATURE_ANNOUNCEMENT'\n | 'HOLIDAY_GREETING'\n // System Events\n | 'SYSTEM_MAINTENANCE'\n | 'APP_UPDATE_AVAILABLE'\n | 'DATA_EXPORT_READY'\n // Activity Events (Generic CRUD)\n | 'ITEM_CREATED'\n | 'ITEM_UPDATED'\n | 'ITEM_DELETED'\n | 'BULK_OPERATION_COMPLETE';\n\n// ============================================================================\n// BASE NOTIFICATION INTERFACE\n// ============================================================================\n\n/**\n * Base notification fields shared across all notification types\n */\nexport interface BaseNotification {\n /** Unique notification ID */\n id: string;\n /** Notification title */\n title: string;\n /** Notification message/body */\n message: string;\n /** Visual type for styling */\n type: NotificationType;\n /** Category for grouping/filtering */\n category: NotificationCategory;\n /** Whether the notification has been read */\n isRead: boolean;\n /** Whether this notification is important/pinned */\n isImportant?: boolean;\n /** Optional action URL to navigate to */\n actionUrl?: string;\n /** Optional action button text */\n actionText?: string;\n /** When the notification was created */\n createdAt: Date | Timestamp;\n /** When the notification was read */\n readAt?: Date | Timestamp;\n /** Additional metadata for custom use */\n metadata?: Record<string, unknown>;\n}\n\n// ============================================================================\n// USER NOTIFICATION\n// ============================================================================\n\n/**\n * User-specific notification stored in consumer project's Firebase\n * Collection: {prefix}_notifications/{notificationId}\n */\nexport interface UserNotification extends BaseNotification {\n /** User ID this notification belongs to */\n userId: string;\n /** How the notification was generated */\n source: NotificationSource;\n /** Reference to source entity (broadcast ID, event ID, etc.) */\n sourceId?: string;\n /** Event type if triggered by event */\n eventType?: StandardEventType | string;\n /** When the notification expires (auto-delete) */\n expiresAt?: Date | Timestamp;\n}\n\n/**\n * Input for creating a user notification\n */\nexport interface CreateUserNotificationInput {\n userId: string;\n title: string;\n message: string;\n type: NotificationType;\n category: NotificationCategory;\n source: NotificationSource;\n sourceId?: string;\n eventType?: StandardEventType | string;\n isImportant?: boolean;\n actionUrl?: string;\n actionText?: string;\n expiresAt?: Date;\n metadata?: Record<string, unknown>;\n}\n\n// ============================================================================\n// BROADCAST NOTIFICATION\n// ============================================================================\n\n/**\n * Cross-project broadcast notification stored in shared-features Firebase\n * Collection: zaions_broadcasts/{broadcastId}\n */\nexport interface BroadcastNotification extends BaseNotification {\n /** Target project IDs (empty = all projects) */\n targetProjects: string[];\n /** Target platforms */\n targetPlatforms: NotificationPlatform[];\n /** Target audience */\n targetAudience: NotificationAudience;\n /** Broadcast status */\n status: BroadcastStatus;\n /** When the broadcast becomes active */\n startDate: Date | Timestamp;\n /** When the broadcast ends (null = no end) */\n endDate?: Date | Timestamp | null;\n /** Display priority (1-100, higher = more important) */\n priority: number;\n /** Whether user can dismiss this broadcast */\n dismissible: boolean;\n /** How to display this broadcast */\n variant: BroadcastVariant;\n /** Total impressions count */\n impressions: number;\n /** Total clicks count */\n clicks: number;\n /** Admin user ID who created */\n createdBy: string;\n /** Admin user ID who last updated */\n updatedBy?: string;\n}\n\n/**\n * Input for creating a broadcast\n */\nexport interface CreateBroadcastInput {\n title: string;\n message: string;\n type: NotificationType;\n category: NotificationCategory;\n targetProjects: string[];\n targetPlatforms: NotificationPlatform[];\n targetAudience: NotificationAudience;\n startDate: Date;\n endDate?: Date | null;\n priority: number;\n dismissible: boolean;\n variant: BroadcastVariant;\n isImportant?: boolean;\n actionUrl?: string;\n actionText?: string;\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Input for updating a broadcast\n */\nexport interface UpdateBroadcastInput extends Partial<CreateBroadcastInput> {\n id: string;\n status?: BroadcastStatus;\n}\n\n// ============================================================================\n// NOTIFICATION TEMPLATE\n// ============================================================================\n\n/**\n * Notification template for standard events\n * Collection: zaions_notification_templates/{templateId}\n */\nexport interface NotificationTemplate {\n /** Template ID */\n id: string;\n /** Template name for admin reference */\n name: string;\n /** Event type this template is for */\n eventType: StandardEventType | string;\n /** Notification category */\n category: NotificationCategory;\n /** Title with placeholders: \"Welcome to {{appName}}, {{userName}}!\" */\n title: string;\n /** Message with placeholders */\n message: string;\n /** List of variable names used in title/message */\n variables: string[];\n /** Visual notification type */\n type: NotificationType;\n /** Whether notifications from this template are important */\n isImportant: boolean;\n /** Default action URL (can use placeholders) */\n actionUrl?: string;\n /** Default action button text */\n actionText?: string;\n /** Whether this template is enabled */\n enabled: boolean;\n /** When template was created */\n createdAt: Date | Timestamp;\n /** When template was last updated */\n updatedAt: Date | Timestamp;\n}\n\n/**\n * Input for creating a template\n */\nexport interface CreateTemplateInput {\n name: string;\n eventType: StandardEventType | string;\n category: NotificationCategory;\n title: string;\n message: string;\n variables: string[];\n type: NotificationType;\n isImportant: boolean;\n actionUrl?: string;\n actionText?: string;\n enabled: boolean;\n}\n\n// ============================================================================\n// USER NOTIFICATION PREFERENCES\n// ============================================================================\n\n/**\n * Category preference settings\n */\nexport interface CategoryPreference {\n /** Show in-app notifications for this category */\n inApp: boolean;\n /** Send push notifications for this category */\n push: boolean;\n /** Send email notifications for this category */\n email: boolean;\n}\n\n/**\n * Quiet hours configuration\n */\nexport interface QuietHoursConfig {\n /** Whether quiet hours are enabled */\n enabled: boolean;\n /** Start time in 24h format: \"22:00\" */\n start: string;\n /** End time in 24h format: \"08:00\" */\n end: string;\n /** User's timezone (IANA format) */\n timezone: string;\n}\n\n/**\n * Email digest configuration\n */\nexport interface EmailDigestConfig {\n /** Whether email digest is enabled */\n enabled: boolean;\n /** Digest frequency */\n frequency: 'daily' | 'weekly' | 'none';\n}\n\n/**\n * Push notification configuration\n */\nexport interface PushConfig {\n /** Whether push is enabled */\n enabled: boolean;\n /** OneSignal player ID */\n playerId?: string;\n /** Web push subscription */\n webPushSubscription?: PushSubscription;\n}\n\n/**\n * User notification preferences\n * Collection: {prefix}_notification_preferences/{userId}\n */\nexport interface NotificationPreferences {\n /** User ID */\n userId: string;\n /** Category-specific preferences */\n categories: Record<NotificationCategory, CategoryPreference>;\n /** Quiet hours settings */\n quietHours: QuietHoursConfig;\n /** Email digest settings */\n emailDigest: EmailDigestConfig;\n /** Push notification settings */\n push: PushConfig;\n /** When preferences were last updated */\n updatedAt: Date | Timestamp;\n}\n\n/**\n * Default notification preferences\n */\nexport const DEFAULT_NOTIFICATION_PREFERENCES: Omit<\n NotificationPreferences,\n 'userId' | 'updatedAt'\n> = {\n categories: {\n system: { inApp: true, push: true, email: false },\n account: { inApp: true, push: true, email: true },\n activity: { inApp: true, push: false, email: false },\n report: { inApp: true, push: false, email: true },\n promotional: { inApp: true, push: false, email: false },\n social: { inApp: true, push: true, email: false },\n },\n quietHours: {\n enabled: false,\n start: '22:00',\n end: '08:00',\n timezone: 'UTC',\n },\n emailDigest: {\n enabled: false,\n frequency: 'none',\n },\n push: {\n enabled: false,\n },\n};\n\n// ============================================================================\n// NOTIFICATION EVENTS\n// ============================================================================\n\n/**\n * Event definition for triggering notifications\n */\nexport interface NotificationEventDefinition {\n /** Event type identifier */\n type: StandardEventType | string;\n /** Event display name */\n name: string;\n /** Event description */\n description: string;\n /** Default notification category */\n category: NotificationCategory;\n /** Default notification type */\n notificationType: NotificationType;\n /** Default priority */\n priority: NotificationPriority;\n /** Available template variables */\n variables: string[];\n /** Whether this event is enabled by default */\n defaultEnabled: boolean;\n}\n\n/**\n * Event trigger payload\n */\nexport interface NotificationEventPayload {\n /** Event type */\n type: StandardEventType | string;\n /** User ID to notify */\n userId: string;\n /** Variable values for template interpolation */\n data: Record<string, string | number | boolean>;\n /** Optional override for notification title */\n titleOverride?: string;\n /** Optional override for notification message */\n messageOverride?: string;\n /** Optional action URL */\n actionUrl?: string;\n /** Optional action text */\n actionText?: string;\n /** Additional metadata */\n metadata?: Record<string, unknown>;\n}\n\n// ============================================================================\n// ANALYTICS TYPES\n// ============================================================================\n\n/**\n * Broadcast analytics summary\n */\nexport interface BroadcastAnalytics {\n broadcastId: string;\n title: string;\n status: BroadcastStatus;\n impressions: number;\n clicks: number;\n dismissals: number;\n ctr: number;\n byPlatform: Record<NotificationPlatform, { impressions: number; clicks: number }>;\n byProject: Record<string, { impressions: number; clicks: number }>;\n byDate: Array<{\n date: string;\n impressions: number;\n clicks: number;\n }>;\n}\n\n/**\n * Overall notification analytics\n */\nexport interface NotificationAnalytics {\n /** Total notifications sent */\n totalSent: number;\n /** Total notifications read */\n totalRead: number;\n /** Total notifications clicked */\n totalClicked: number;\n /** Read rate (read/sent) */\n readRate: number;\n /** Click rate (clicked/sent) */\n clickRate: number;\n /** Breakdown by category */\n byCategory: Record<\n NotificationCategory,\n {\n sent: number;\n read: number;\n clicked: number;\n }\n >;\n /** Breakdown by type */\n byType: Record<\n NotificationType,\n {\n sent: number;\n read: number;\n clicked: number;\n }\n >;\n /** Daily breakdown */\n byDate: Array<{\n date: string;\n sent: number;\n read: number;\n clicked: number;\n }>;\n}\n\n// ============================================================================\n// COMPONENT PROPS\n// ============================================================================\n\n/**\n * Props for NotificationBell component\n */\nexport interface NotificationBellProps {\n /** Additional CSS classes */\n className?: string;\n /** Icon size in pixels */\n size?: number;\n /** Show count badge even when 0 */\n showZeroBadge?: boolean;\n /** Custom onClick handler (default: toggle panel) */\n onClick?: () => void;\n}\n\n/**\n * Props for NotificationPanel component\n */\nexport interface NotificationPanelProps {\n /** Whether the panel is open */\n isOpen: boolean;\n /** Called when panel should close */\n onClose: () => void;\n /** Maximum height for the panel */\n maxHeight?: string;\n /** Whether to show the filter tabs */\n showFilters?: boolean;\n /** Custom empty state component */\n emptyStateComponent?: React.ReactNode;\n}\n\n/**\n * Props for NotificationCard component\n */\nexport interface NotificationCardProps {\n /** The notification to display */\n notification: UserNotification;\n /** Called when notification is clicked */\n onClick?: () => void;\n /** Called when delete button is clicked */\n onDelete?: () => void;\n /** Whether to show delete button */\n showDelete?: boolean;\n /** Whether to show timestamp */\n showTimestamp?: boolean;\n}\n\n/**\n * Props for BroadcastBanner component\n */\nexport interface BroadcastBannerProps {\n /** The broadcast to display */\n broadcast: BroadcastNotification;\n /** Called when CTA is clicked */\n onActionClick?: () => void;\n /** Called when banner is dismissed */\n onDismiss?: () => void;\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Props for AnnouncementModal component\n */\nexport interface AnnouncementModalProps {\n /** The broadcast to display */\n broadcast: BroadcastNotification;\n /** Whether the modal is open */\n isOpen: boolean;\n /** Called when modal should close */\n onClose: () => void;\n /** Called when CTA is clicked */\n onActionClick?: () => void;\n}\n\n/**\n * Props for NotificationPreferences component\n */\nexport interface NotificationPreferencesProps {\n /** Current preferences */\n preferences: NotificationPreferences;\n /** Called when preferences change */\n onPreferencesChange: (preferences: NotificationPreferences) => void;\n /** Whether saving is in progress */\n isSaving?: boolean;\n /** Categories to show (default: all) */\n visibleCategories?: NotificationCategory[];\n /** Whether to show push settings */\n showPushSettings?: boolean;\n /** Whether to show email settings */\n showEmailSettings?: boolean;\n /** Whether to show quiet hours settings */\n showQuietHours?: boolean;\n}\n\n// ============================================================================\n// HOOK RETURN TYPES\n// ============================================================================\n\n/**\n * Return type for useNotifications hook\n */\nexport interface UseNotificationsReturn {\n /** List of notifications */\n notifications: UserNotification[];\n /** Number of unread notifications */\n unreadCount: number;\n /** Whether notifications are loading */\n isLoading: boolean;\n /** Error if any */\n error: Error | null;\n /** Mark a notification as read */\n markAsRead: (notificationId: string) => Promise<void>;\n /** Mark all notifications as read */\n markAllAsRead: () => Promise<void>;\n /** Delete a notification */\n deleteNotification: (notificationId: string) => Promise<void>;\n /** Clear all notifications */\n clearAll: () => Promise<void>;\n /** Refresh notifications */\n refresh: () => Promise<void>;\n}\n\n/**\n * Return type for useBroadcasts hook\n */\nexport interface UseBroadcastsReturn {\n /** List of active broadcasts */\n broadcasts: BroadcastNotification[];\n /** Whether broadcasts are loading */\n isLoading: boolean;\n /** Error if any */\n error: Error | null;\n /** Dismiss a broadcast */\n dismissBroadcast: (broadcastId: string) => void;\n /** Track broadcast impression */\n trackImpression: (broadcastId: string) => void;\n /** Track broadcast click */\n trackClick: (broadcastId: string) => void;\n /** Check if broadcast was dismissed */\n isDismissed: (broadcastId: string) => boolean;\n /** Refresh broadcasts from cache */\n refresh: () => Promise<void>;\n}\n\n/**\n * Return type for useNotificationEvents hook\n */\nexport interface UseNotificationEventsReturn {\n /** Trigger a notification event */\n trigger: (payload: NotificationEventPayload) => Promise<void>;\n /** Trigger account created event */\n triggerAccountCreated: (data: { userName: string; email: string }) => Promise<void>;\n /** Trigger new device signin event */\n triggerNewDeviceSignin: (data: { deviceName: string; location?: string }) => Promise<void>;\n /** Trigger password changed event */\n triggerPasswordChanged: () => Promise<void>;\n /** Trigger profile updated event */\n triggerProfileUpdated: (data: { changes: string[] }) => Promise<void>;\n /** Trigger CRUD event */\n triggerCrudEvent: (data: {\n action: 'created' | 'updated' | 'deleted';\n entityType: string;\n entityName: string;\n }) => Promise<void>;\n /** Trigger app tip event */\n triggerAppTip: (data: { tipId: string; title: string; body: string }) => Promise<void>;\n}\n\n// ============================================================================\n// SERVICE TYPES\n// ============================================================================\n\n/**\n * Options for fetching broadcasts\n */\nexport interface FetchBroadcastsOptions {\n /** Filter by project ID */\n projectId?: string;\n /** Filter by platform */\n platform?: NotificationPlatform;\n /** Filter by variant */\n variant?: BroadcastVariant;\n /** Filter by status */\n status?: BroadcastStatus;\n /** Maximum results */\n limit?: number;\n}\n\n/**\n * Options for fetching user notifications\n */\nexport interface FetchNotificationsOptions {\n /** User ID */\n userId: string;\n /** Filter by category */\n category?: NotificationCategory;\n /** Filter by read status */\n isRead?: boolean;\n /** Maximum results */\n limit?: number;\n /** Offset for pagination */\n offset?: number;\n /** Start date filter */\n startDate?: Date;\n /** End date filter */\n endDate?: Date;\n}\n\n// ============================================================================\n// COLLECTION NAMES\n// ============================================================================\n\n/**\n * Shared collections (stored in shared-features Firebase)\n */\nexport const NOTIFICATION_COLLECTIONS = {\n /** Cross-project broadcasts */\n BROADCASTS: 'zaions_broadcasts',\n /** Notification templates */\n TEMPLATES: 'zaions_notification_templates',\n /** Broadcast events/analytics */\n BROADCAST_EVENTS: 'zaions_broadcast_events',\n} as const;\n\n/**\n * Get consumer project collection names\n * @param prefix - Project prefix (e.g., 'pp' for pregnancy-pal)\n */\nexport const getNotificationCollections = (prefix: string) =>\n ({\n /** User notifications */\n NOTIFICATIONS: `${prefix}_notifications`,\n /** User notification preferences */\n PREFERENCES: `${prefix}_notification_preferences`,\n /** Push subscriptions */\n PUSH_SUBSCRIPTIONS: `${prefix}_push_subscriptions`,\n }) as const;\n\n// ============================================================================\n// DISPLAY NAMES & CONSTANTS\n// ============================================================================\n\n/**\n * Category display names\n */\nexport const CATEGORY_NAMES: Record<NotificationCategory, string> = {\n system: 'System',\n account: 'Account',\n activity: 'Activity',\n report: 'Reports',\n promotional: 'Tips & Updates',\n social: 'Social',\n};\n\n/**\n * Category descriptions\n */\nexport const CATEGORY_DESCRIPTIONS: Record<NotificationCategory, string> = {\n system: 'Maintenance updates, outages, and system alerts',\n account: 'Welcome messages, security alerts, and profile changes',\n activity: 'Updates about your actions and changes',\n report: 'Weekly and monthly summaries of your activity',\n promotional: 'Tips, new features, and holiday greetings',\n social: 'Mentions, shares, and comments from others',\n};\n\n/**\n * Notification type display names\n */\nexport const TYPE_NAMES: Record<NotificationType, string> = {\n info: 'Information',\n success: 'Success',\n warning: 'Warning',\n error: 'Error',\n reminder: 'Reminder',\n milestone: 'Milestone',\n announcement: 'Announcement',\n};\n\n/**\n * Priority display names\n */\nexport const PRIORITY_NAMES: Record<NotificationPriority, string> = {\n urgent: 'Urgent',\n high: 'High',\n normal: 'Normal',\n low: 'Low',\n};\n\n/**\n * Event type display names\n */\nexport const EVENT_TYPE_NAMES: Record<StandardEventType, string> = {\n ACCOUNT_CREATED: 'Account Created',\n ACCOUNT_WELCOME: 'Welcome Message',\n NEW_DEVICE_SIGNIN: 'New Device Sign-in',\n PASSWORD_CHANGED: 'Password Changed',\n PROFILE_UPDATED: 'Profile Updated',\n ACCOUNT_DELETED: 'Account Deleted',\n DAILY_SUMMARY: 'Daily Summary',\n WEEKLY_SUMMARY: 'Weekly Summary',\n MONTHLY_SUMMARY: 'Monthly Summary',\n QUARTERLY_SUMMARY: 'Quarterly Summary',\n YEARLY_SUMMARY: 'Yearly Summary',\n APP_TIP: 'App Tip',\n HIDDEN_FEATURE: 'Hidden Feature',\n NEW_FEATURE_ANNOUNCEMENT: 'New Feature',\n HOLIDAY_GREETING: 'Holiday Greeting',\n SYSTEM_MAINTENANCE: 'System Maintenance',\n APP_UPDATE_AVAILABLE: 'App Update Available',\n DATA_EXPORT_READY: 'Data Export Ready',\n ITEM_CREATED: 'Item Created',\n ITEM_UPDATED: 'Item Updated',\n ITEM_DELETED: 'Item Deleted',\n BULK_OPERATION_COMPLETE: 'Bulk Operation Complete',\n};\n\n/**\n * Default broadcast priority\n */\nexport const DEFAULT_BROADCAST_PRIORITY = 50;\n\n/**\n * Maximum notification title length\n */\nexport const MAX_NOTIFICATION_TITLE_LENGTH = 100;\n\n/**\n * Maximum notification message length\n */\nexport const MAX_NOTIFICATION_MESSAGE_LENGTH = 500;\n"],"names":[],"mappings":";;AA2aO,MAAM,yBAAyB;AAK/B,MAAM,4BAA4B;AAKlC,MAAM,gBAA2C;AAAA,EACtD,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,gBAAgB;AAClB;AAKO,MAAM,kBAA+C;AAAA,EAC1D,cAAc;AAAA,EACd,eAAe;AAAA,EACf,eAAe;AAAA,EACf,cAAc;AAAA,EACd,cAAc;AAAA,EACd,eAAe;AAAA,EACf,eAAe;AAAA,EACf,aAAa;AACf;AAKO,MAAM,iBAAiD;AAAA,EAC5D,KAAK;AAAA,EACL,SAAS;AAAA,EACT,KAAK;AAAA,EACL,WAAW;AACb;AASO,MAAM,cAAc;AAAA,EACzB,WAAW;AAAA,EACX,UAAU;AAAA,EACV,aAAa;AAAA,EACb,UAAU;AAAA,EACV,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,cAAc;AAAA,EACd,gBAAgB;AAClB;AC1GO,MAAM,mCAGT;AAAA,EACF,YAAY;AAAA,IACV,QAAQ,EAAE,OAAO,MAAM,MAAM,MAAM,OAAO,MAAA;AAAA,IAC1C,SAAS,EAAE,OAAO,MAAM,MAAM,MAAM,OAAO,KAAA;AAAA,IAC3C,UAAU,EAAE,OAAO,MAAM,MAAM,OAAO,OAAO,MAAA;AAAA,IAC7C,QAAQ,EAAE,OAAO,MAAM,MAAM,OAAO,OAAO,KAAA;AAAA,IAC3C,aAAa,EAAE,OAAO,MAAM,MAAM,OAAO,OAAO,MAAA;AAAA,IAChD,QAAQ,EAAE,OAAO,MAAM,MAAM,MAAM,OAAO,MAAA;AAAA,EAAM;AAAA,EAElD,YAAY;AAAA,IACV,SAAS;AAAA,IACT,OAAO;AAAA,IACP,KAAK;AAAA,IACL,UAAU;AAAA,EAAA;AAAA,EAEZ,aAAa;AAAA,IACX,SAAS;AAAA,IACT,WAAW;AAAA,EAAA;AAAA,EAEb,MAAM;AAAA,IACJ,SAAS;AAAA,EAAA;AAEb;AA8UO,MAAM,2BAA2B;AAAA;AAAA,EAEtC,YAAY;AAAA;AAAA,EAEZ,WAAW;AAAA;AAAA,EAEX,kBAAkB;AACpB;AAMO,MAAM,6BAA6B,CAAC,YACxC;AAAA;AAAA,EAEC,eAAe,GAAG,MAAM;AAAA;AAAA,EAExB,aAAa,GAAG,MAAM;AAAA;AAAA,EAEtB,oBAAoB,GAAG,MAAM;AAC/B;AASK,MAAM,iBAAuD;AAAA,EAClE,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,QAAQ;AACV;AAKO,MAAM,wBAA8D;AAAA,EACzE,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,QAAQ;AACV;AAKO,MAAM,aAA+C;AAAA,EAC1D,MAAM;AAAA,EACN,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AAAA,EACP,UAAU;AAAA,EACV,WAAW;AAAA,EACX,cAAc;AAChB;AAKO,MAAM,iBAAuD;AAAA,EAClE,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,KAAK;AACP;AAKO,MAAM,mBAAsD;AAAA,EACjE,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,gBAAgB;AAAA,EAChB,SAAS;AAAA,EACT,gBAAgB;AAAA,EAChB,0BAA0B;AAAA,EAC1B,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,mBAAmB;AAAA,EACnB,cAAc;AAAA,EACd,cAAc;AAAA,EACd,cAAc;AAAA,EACd,yBAAyB;AAC3B;AAKO,MAAM,6BAA6B;AAKnC,MAAM,gCAAgC;AAKtC,MAAM,kCAAkC;;;;;;;;;;;;;;;;;;"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -6,5 +6,6 @@
|
|
|
6
6
|
* @author Ahsan Mahmood <aoneahsan@gmail.com>
|
|
7
7
|
*/
|
|
8
8
|
export * from './campaigns';
|
|
9
|
+
export * from './notifications';
|
|
9
10
|
export type { FirebaseConfig, ConsumerPlatform, SharedFeaturesConfig, SharedFeaturesState, } from '../firebase/config';
|
|
10
11
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,cAAc,aAAa,CAAC;AAG5B,YAAY,EACV,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,cAAc,aAAa,CAAC;AAG5B,cAAc,iBAAiB,CAAC;AAGhC,YAAY,EACV,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,oBAAoB,CAAC"}
|
package/dist/types/index.js
CHANGED
|
@@ -38,12 +38,120 @@ const COLLECTIONS = {
|
|
|
38
38
|
SOCIAL_LINKS: "zaions_social_links",
|
|
39
39
|
DEVELOPER_INFO: "zaions_developer_info"
|
|
40
40
|
};
|
|
41
|
+
const DEFAULT_NOTIFICATION_PREFERENCES = {
|
|
42
|
+
categories: {
|
|
43
|
+
system: { inApp: true, push: true, email: false },
|
|
44
|
+
account: { inApp: true, push: true, email: true },
|
|
45
|
+
activity: { inApp: true, push: false, email: false },
|
|
46
|
+
report: { inApp: true, push: false, email: true },
|
|
47
|
+
promotional: { inApp: true, push: false, email: false },
|
|
48
|
+
social: { inApp: true, push: true, email: false }
|
|
49
|
+
},
|
|
50
|
+
quietHours: {
|
|
51
|
+
enabled: false,
|
|
52
|
+
start: "22:00",
|
|
53
|
+
end: "08:00",
|
|
54
|
+
timezone: "UTC"
|
|
55
|
+
},
|
|
56
|
+
emailDigest: {
|
|
57
|
+
enabled: false,
|
|
58
|
+
frequency: "none"
|
|
59
|
+
},
|
|
60
|
+
push: {
|
|
61
|
+
enabled: false
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
const NOTIFICATION_COLLECTIONS = {
|
|
65
|
+
/** Cross-project broadcasts */
|
|
66
|
+
BROADCASTS: "zaions_broadcasts",
|
|
67
|
+
/** Notification templates */
|
|
68
|
+
TEMPLATES: "zaions_notification_templates",
|
|
69
|
+
/** Broadcast events/analytics */
|
|
70
|
+
BROADCAST_EVENTS: "zaions_broadcast_events"
|
|
71
|
+
};
|
|
72
|
+
const getNotificationCollections = (prefix) => ({
|
|
73
|
+
/** User notifications */
|
|
74
|
+
NOTIFICATIONS: `${prefix}_notifications`,
|
|
75
|
+
/** User notification preferences */
|
|
76
|
+
PREFERENCES: `${prefix}_notification_preferences`,
|
|
77
|
+
/** Push subscriptions */
|
|
78
|
+
PUSH_SUBSCRIPTIONS: `${prefix}_push_subscriptions`
|
|
79
|
+
});
|
|
80
|
+
const CATEGORY_NAMES = {
|
|
81
|
+
system: "System",
|
|
82
|
+
account: "Account",
|
|
83
|
+
activity: "Activity",
|
|
84
|
+
report: "Reports",
|
|
85
|
+
promotional: "Tips & Updates",
|
|
86
|
+
social: "Social"
|
|
87
|
+
};
|
|
88
|
+
const CATEGORY_DESCRIPTIONS = {
|
|
89
|
+
system: "Maintenance updates, outages, and system alerts",
|
|
90
|
+
account: "Welcome messages, security alerts, and profile changes",
|
|
91
|
+
activity: "Updates about your actions and changes",
|
|
92
|
+
report: "Weekly and monthly summaries of your activity",
|
|
93
|
+
promotional: "Tips, new features, and holiday greetings",
|
|
94
|
+
social: "Mentions, shares, and comments from others"
|
|
95
|
+
};
|
|
96
|
+
const TYPE_NAMES = {
|
|
97
|
+
info: "Information",
|
|
98
|
+
success: "Success",
|
|
99
|
+
warning: "Warning",
|
|
100
|
+
error: "Error",
|
|
101
|
+
reminder: "Reminder",
|
|
102
|
+
milestone: "Milestone",
|
|
103
|
+
announcement: "Announcement"
|
|
104
|
+
};
|
|
105
|
+
const PRIORITY_NAMES = {
|
|
106
|
+
urgent: "Urgent",
|
|
107
|
+
high: "High",
|
|
108
|
+
normal: "Normal",
|
|
109
|
+
low: "Low"
|
|
110
|
+
};
|
|
111
|
+
const EVENT_TYPE_NAMES = {
|
|
112
|
+
ACCOUNT_CREATED: "Account Created",
|
|
113
|
+
ACCOUNT_WELCOME: "Welcome Message",
|
|
114
|
+
NEW_DEVICE_SIGNIN: "New Device Sign-in",
|
|
115
|
+
PASSWORD_CHANGED: "Password Changed",
|
|
116
|
+
PROFILE_UPDATED: "Profile Updated",
|
|
117
|
+
ACCOUNT_DELETED: "Account Deleted",
|
|
118
|
+
DAILY_SUMMARY: "Daily Summary",
|
|
119
|
+
WEEKLY_SUMMARY: "Weekly Summary",
|
|
120
|
+
MONTHLY_SUMMARY: "Monthly Summary",
|
|
121
|
+
QUARTERLY_SUMMARY: "Quarterly Summary",
|
|
122
|
+
YEARLY_SUMMARY: "Yearly Summary",
|
|
123
|
+
APP_TIP: "App Tip",
|
|
124
|
+
HIDDEN_FEATURE: "Hidden Feature",
|
|
125
|
+
NEW_FEATURE_ANNOUNCEMENT: "New Feature",
|
|
126
|
+
HOLIDAY_GREETING: "Holiday Greeting",
|
|
127
|
+
SYSTEM_MAINTENANCE: "System Maintenance",
|
|
128
|
+
APP_UPDATE_AVAILABLE: "App Update Available",
|
|
129
|
+
DATA_EXPORT_READY: "Data Export Ready",
|
|
130
|
+
ITEM_CREATED: "Item Created",
|
|
131
|
+
ITEM_UPDATED: "Item Updated",
|
|
132
|
+
ITEM_DELETED: "Item Deleted",
|
|
133
|
+
BULK_OPERATION_COMPLETE: "Bulk Operation Complete"
|
|
134
|
+
};
|
|
135
|
+
const DEFAULT_BROADCAST_PRIORITY = 50;
|
|
136
|
+
const MAX_NOTIFICATION_TITLE_LENGTH = 100;
|
|
137
|
+
const MAX_NOTIFICATION_MESSAGE_LENGTH = 500;
|
|
41
138
|
export {
|
|
139
|
+
CATEGORY_DESCRIPTIONS,
|
|
140
|
+
CATEGORY_NAMES,
|
|
42
141
|
COLLECTIONS,
|
|
142
|
+
DEFAULT_BROADCAST_PRIORITY,
|
|
43
143
|
DEFAULT_CAMPAIGN_PRIORITY,
|
|
44
144
|
DEFAULT_FREQUENCY_DAYS,
|
|
145
|
+
DEFAULT_NOTIFICATION_PREFERENCES,
|
|
146
|
+
EVENT_TYPE_NAMES,
|
|
147
|
+
MAX_NOTIFICATION_MESSAGE_LENGTH,
|
|
148
|
+
MAX_NOTIFICATION_TITLE_LENGTH,
|
|
149
|
+
NOTIFICATION_COLLECTIONS,
|
|
45
150
|
PLACEMENT_NAMES,
|
|
46
151
|
PLATFORM_NAMES,
|
|
47
|
-
|
|
152
|
+
PRIORITY_NAMES,
|
|
153
|
+
TYPE_NAMES,
|
|
154
|
+
VARIANT_NAMES,
|
|
155
|
+
getNotificationCollections
|
|
48
156
|
};
|
|
49
157
|
//# sourceMappingURL=index.js.map
|
package/dist/types/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/types/campaigns.ts"],"sourcesContent":["/**\n * Campaign/Advertising System Type Definitions\n *\n * Type definitions for the centralized advertising system including\n * Firestore document schemas, service interfaces, and UI types.\n *\n * Based on ZTools advertising system, adapted for cross-project use.\n *\n * @author Ahsan Mahmood <aoneahsan@gmail.com>\n */\n\nimport { Timestamp } from 'firebase/firestore';\n\n// ============================================================================\n// PRODUCT TYPES\n// ============================================================================\n\n/**\n * Product type classification\n */\nexport type ProductType = 'extension' | 'android' | 'ios' | 'web';\n\n/**\n * Product information for advertising\n */\nexport interface Product {\n /** Unique product identifier */\n id: string;\n /** Product display name */\n name: string;\n /** Short tagline (marketing slogan) */\n tagline: string;\n /** Longer description of the product */\n description: string;\n /** Product type classification */\n type: ProductType;\n /** URL to the product (store link or website) */\n url: string;\n /** Brand/theme color (hex) */\n color: string;\n /** Key features list (3-4 items) */\n features: string[];\n /** Inline SVG icon (64px) */\n icon64?: string;\n /** Inline SVG icon (128px) */\n icon128?: string;\n /** Chrome Web Store URL */\n chromeStoreUrl?: string;\n /** Google Play Store URL */\n playStoreUrl?: string;\n /** Apple App Store URL */\n appStoreUrl?: string;\n /** Web app URL */\n webUrl?: string;\n /** Whether the product is active */\n enabled: boolean;\n /** When the product was created */\n createdAt: Timestamp;\n /** When the product was last updated */\n updatedAt: Timestamp;\n}\n\n// ============================================================================\n// CAMPAIGN TYPES\n// ============================================================================\n\n/**\n * Campaign status values\n */\nexport type CampaignStatus = 'active' | 'paused' | 'scheduled' | 'ended';\n\n/**\n * Target platforms for campaigns\n */\nexport type TargetPlatform = 'web' | 'android' | 'ios' | 'extension';\n\n/**\n * Target audience for campaigns\n */\nexport type TargetAudience = 'all' | 'authenticated' | 'anonymous';\n\n/**\n * Placement options for ads\n */\nexport type AdPlacement =\n | 'popup_slider'\n | 'options_panel'\n | 'onetime_modal'\n | 'update_modal'\n | 'notification'\n | 'footer_slider'\n | 'sidebar_panel'\n | 'home_banner';\n\n/**\n * Small panel variant styles\n */\nexport type SmallPanelVariant =\n | 'small_panel_1' // Minimal\n | 'small_panel_2' // Tagline\n | 'small_panel_3' // Features\n | 'small_panel_4' // Gradient\n | 'small_panel_5'; // Card\n\n/**\n * Large slider variant styles\n */\nexport type LargePanelVariant =\n | 'large_slider_1' // Hero\n | 'large_slider_2' // Feature Grid\n | 'large_slider_3' // Testimonial\n | 'large_slider_4' // Comparison\n | 'large_slider_5'; // Video Placeholder\n\n/**\n * All ad variant types\n */\nexport type AdVariant = SmallPanelVariant | LargePanelVariant;\n\n/**\n * Advertising campaign document\n * Stored in: zaions_campaigns/{campaignId}\n */\nexport interface Campaign {\n /** Campaign document ID */\n id: string;\n /** Reference to product being promoted */\n productId: string;\n /** Campaign name (admin reference) */\n name: string;\n /** Current campaign status */\n status: CampaignStatus;\n\n // === TARGETING ===\n /** Platforms where this campaign should show */\n targetPlatforms: TargetPlatform[];\n /** Audience type to target */\n targetAudience: TargetAudience;\n /** Specific projects to target (empty = all projects) */\n targetProjects: string[];\n /** Don't show to users already using this product */\n excludeProductUsers: boolean;\n\n // === DISPLAY RULES ===\n /** Where the ad can be displayed */\n placements: AdPlacement[];\n /** Priority (1-100, higher = more important) */\n priority: number;\n /** Days between impressions for same user (default: 20) */\n frequencyDays: number;\n /** Maximum total impressions (null = unlimited) */\n maxImpressions: number | null;\n\n // === TIMELINE ===\n /** Campaign start date */\n startDate: Timestamp;\n /** Campaign end date (null = no end) */\n endDate: Timestamp | null;\n\n // === CREATIVE ===\n /** UI variant to use */\n variant: AdVariant;\n /** Custom title (overrides product name) */\n customTitle?: string;\n /** Custom tagline (overrides product tagline) */\n customTagline?: string;\n /** Custom CTA button text */\n customCta?: string;\n /** Custom CTA button URL (overrides product URL) */\n customCtaUrl?: string;\n /** Custom description (overrides product description) */\n customDescription?: string;\n /** Custom product color for custom products/projects */\n customProductColor?: string;\n /** Custom icon SVG string (for custom products) */\n customIcon?: string;\n /** Custom features list (for custom products) */\n customFeatures?: string[];\n\n // === METRICS (Denormalized) ===\n /** Total number of impressions */\n totalImpressions: number;\n /** Total number of clicks */\n totalClicks: number;\n /** Total number of closes/dismissals */\n totalCloses: number;\n\n // === METADATA ===\n /** When campaign was created */\n createdAt: Timestamp;\n /** When campaign was last updated */\n updatedAt: Timestamp;\n /** Admin user ID who created */\n createdBy: string;\n /** Admin user ID who last updated */\n updatedBy?: string;\n}\n\n/**\n * Input for creating a new campaign\n */\nexport interface CreateCampaignInput {\n productId: string;\n name: string;\n status: CampaignStatus;\n targetPlatforms: TargetPlatform[];\n targetAudience: TargetAudience;\n targetProjects: string[];\n excludeProductUsers: boolean;\n placements: AdPlacement[];\n priority: number;\n frequencyDays: number;\n maxImpressions: number | null;\n startDate: Date;\n endDate: Date | null;\n variant: AdVariant;\n customTitle?: string;\n customTagline?: string;\n customCta?: string;\n customCtaUrl?: string;\n customDescription?: string;\n customProductColor?: string;\n customIcon?: string;\n customFeatures?: string[];\n}\n\n/**\n * Input for updating a campaign\n */\nexport interface UpdateCampaignInput extends Partial<CreateCampaignInput> {\n id: string;\n}\n\n// ============================================================================\n// IMPRESSION TYPES\n// ============================================================================\n\n/**\n * Types of ad interactions\n */\nexport type AdAction = 'impression' | 'click' | 'close' | 'notification_click';\n\n/**\n * Ad impression/interaction event\n * Stored in: zaions_impressions/{impressionId}\n */\nexport interface Impression {\n /** Impression document ID */\n id: string;\n /** Campaign that generated this impression */\n campaignId: string;\n /** Product being advertised */\n productId: string;\n /** Project where impression occurred */\n projectId: string;\n\n /** User ID (null for anonymous) */\n userId: string | null;\n /** Device/browser fingerprint */\n deviceId: string;\n /** Platform where impression occurred */\n platform: TargetPlatform;\n /** Placement where ad was shown */\n placement: AdPlacement;\n\n /** Type of interaction */\n action: AdAction;\n /** When the interaction occurred */\n timestamp: Timestamp;\n\n /** UI variant that was displayed */\n variant: AdVariant;\n /** Session identifier */\n sessionId?: string;\n}\n\n/**\n * Input for recording an impression\n */\nexport interface RecordImpressionInput {\n campaignId: string;\n productId: string;\n placement: AdPlacement;\n action: AdAction;\n variant: AdVariant;\n sessionId?: string;\n}\n\n// ============================================================================\n// AD HISTORY TYPES\n// ============================================================================\n\n/**\n * Local ad history entry (for frequency capping)\n */\nexport interface AdHistoryEntry {\n /** Campaign ID */\n campaignId: string;\n /** Product ID */\n productId: string;\n /** Last seen timestamp (Unix ms) */\n lastSeenAt: number;\n /** Impression count */\n impressionCount: number;\n /** Whether clicked */\n clicked: boolean;\n /** Whether closed */\n closed: boolean;\n /** Next eligible timestamp (Unix ms) */\n nextEligibleAt: number;\n}\n\n// ============================================================================\n// SERVICE TYPES\n// ============================================================================\n\n/**\n * Options for fetching campaigns\n */\nexport interface FetchCampaignsOptions {\n /** Filter by placement */\n placement?: AdPlacement;\n /** Filter by status */\n status?: CampaignStatus;\n /** Filter by product */\n productId?: string;\n /** Maximum results */\n limit?: number;\n}\n\n/**\n * Campaign with resolved product data\n */\nexport interface CampaignWithProduct extends Campaign {\n /** Resolved product information */\n product: Product;\n}\n\n// ============================================================================\n// ANALYTICS TYPES\n// ============================================================================\n\n/**\n * Campaign analytics summary\n */\nexport interface CampaignAnalytics {\n campaignId: string;\n campaignName: string;\n productId: string;\n productName: string;\n\n /** Total impressions */\n impressions: number;\n /** Total clicks */\n clicks: number;\n /** Total closes */\n closes: number;\n /** Click-through rate (clicks/impressions) */\n ctr: number;\n /** Close rate (closes/impressions) */\n closeRate: number;\n\n /** Breakdown by platform */\n byPlatform: Record<TargetPlatform, { impressions: number; clicks: number }>;\n /** Breakdown by placement */\n byPlacement: Record<AdPlacement, { impressions: number; clicks: number }>;\n /** Breakdown by project */\n byProject: Record<string, { impressions: number; clicks: number }>;\n /** Daily breakdown */\n byDate: Array<{\n date: string;\n impressions: number;\n clicks: number;\n closes: number;\n }>;\n}\n\n// ============================================================================\n// COMPONENT PROPS\n// ============================================================================\n\n/**\n * Props for small panel variant components\n */\nexport interface SmallPanelProps {\n /** Campaign with product data */\n campaign: CampaignWithProduct;\n /** Called when user clicks CTA */\n onCTAClick?: () => void;\n /** Called when user closes/dismisses the ad */\n onClose?: () => void;\n}\n\n/**\n * Props for large panel variant components\n */\nexport interface LargePanelProps {\n /** Campaign with product data */\n campaign: CampaignWithProduct;\n /** Called when user clicks CTA */\n onCTAClick?: () => void;\n /** Called when user closes/dismisses the ad */\n onClose?: () => void;\n /** Whether to show slide indicator */\n showIndicator?: boolean;\n /** Current slide index (for carousel) */\n currentIndex?: number;\n /** Total number of slides (for carousel) */\n totalCount?: number;\n}\n\n/**\n * Props for ad panel component\n */\nexport interface AdPanelProps {\n placement: AdPlacement;\n variant?: SmallPanelVariant;\n className?: string;\n}\n\n// ============================================================================\n// DEFAULT VALUES\n// ============================================================================\n\n/**\n * Default frequency cap in days\n */\nexport const DEFAULT_FREQUENCY_DAYS = 20;\n\n/**\n * Default campaign priority\n */\nexport const DEFAULT_CAMPAIGN_PRIORITY = 50;\n\n/**\n * Variant display names\n */\nexport const VARIANT_NAMES: Record<AdVariant, string> = {\n small_panel_1: 'Minimal',\n small_panel_2: 'Tagline',\n small_panel_3: 'Features',\n small_panel_4: 'Gradient',\n small_panel_5: 'Card',\n large_slider_1: 'Hero',\n large_slider_2: 'Feature Grid',\n large_slider_3: 'Testimonial',\n large_slider_4: 'Comparison',\n large_slider_5: 'Video Placeholder',\n};\n\n/**\n * Placement display names\n */\nexport const PLACEMENT_NAMES: Record<AdPlacement, string> = {\n popup_slider: 'Extension Popup Slider',\n options_panel: 'Extension Options Panel',\n onetime_modal: 'One-Time Welcome Modal',\n update_modal: 'Update Announcement Modal',\n notification: 'Browser Notification',\n footer_slider: 'Web App Footer Slider',\n sidebar_panel: 'Web App Sidebar Panel',\n home_banner: 'Home Page Banner',\n};\n\n/**\n * Platform display names\n */\nexport const PLATFORM_NAMES: Record<TargetPlatform, string> = {\n web: 'Web App',\n android: 'Android App',\n ios: 'iOS App',\n extension: 'Browser Extension',\n};\n\n// ============================================================================\n// FIREBASE COLLECTION NAMES\n// ============================================================================\n\n/**\n * Collection names for shared features\n */\nexport const COLLECTIONS = {\n CAMPAIGNS: 'zaions_campaigns',\n PRODUCTS: 'zaions_products',\n IMPRESSIONS: 'zaions_impressions',\n CONTACTS: 'zaions_contacts',\n FEATURE_REQUESTS: 'zaions_feature_requests',\n PAYMENT_OPTIONS: 'zaions_payment_options',\n SOCIAL_LINKS: 'zaions_social_links',\n DEVELOPER_INFO: 'zaions_developer_info',\n} as const;\n"],"names":[],"mappings":"AA2aO,MAAM,yBAAyB;AAK/B,MAAM,4BAA4B;AAKlC,MAAM,gBAA2C;AAAA,EACtD,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,gBAAgB;AAClB;AAKO,MAAM,kBAA+C;AAAA,EAC1D,cAAc;AAAA,EACd,eAAe;AAAA,EACf,eAAe;AAAA,EACf,cAAc;AAAA,EACd,cAAc;AAAA,EACd,eAAe;AAAA,EACf,eAAe;AAAA,EACf,aAAa;AACf;AAKO,MAAM,iBAAiD;AAAA,EAC5D,KAAK;AAAA,EACL,SAAS;AAAA,EACT,KAAK;AAAA,EACL,WAAW;AACb;AASO,MAAM,cAAc;AAAA,EACzB,WAAW;AAAA,EACX,UAAU;AAAA,EACV,aAAa;AAAA,EACb,UAAU;AAAA,EACV,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,cAAc;AAAA,EACd,gBAAgB;AAClB;"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/types/campaigns.ts","../../src/types/notifications.ts"],"sourcesContent":["/**\n * Campaign/Advertising System Type Definitions\n *\n * Type definitions for the centralized advertising system including\n * Firestore document schemas, service interfaces, and UI types.\n *\n * Based on ZTools advertising system, adapted for cross-project use.\n *\n * @author Ahsan Mahmood <aoneahsan@gmail.com>\n */\n\nimport { Timestamp } from 'firebase/firestore';\n\n// ============================================================================\n// PRODUCT TYPES\n// ============================================================================\n\n/**\n * Product type classification\n */\nexport type ProductType = 'extension' | 'android' | 'ios' | 'web';\n\n/**\n * Product information for advertising\n */\nexport interface Product {\n /** Unique product identifier */\n id: string;\n /** Product display name */\n name: string;\n /** Short tagline (marketing slogan) */\n tagline: string;\n /** Longer description of the product */\n description: string;\n /** Product type classification */\n type: ProductType;\n /** URL to the product (store link or website) */\n url: string;\n /** Brand/theme color (hex) */\n color: string;\n /** Key features list (3-4 items) */\n features: string[];\n /** Inline SVG icon (64px) */\n icon64?: string;\n /** Inline SVG icon (128px) */\n icon128?: string;\n /** Chrome Web Store URL */\n chromeStoreUrl?: string;\n /** Google Play Store URL */\n playStoreUrl?: string;\n /** Apple App Store URL */\n appStoreUrl?: string;\n /** Web app URL */\n webUrl?: string;\n /** Whether the product is active */\n enabled: boolean;\n /** When the product was created */\n createdAt: Timestamp;\n /** When the product was last updated */\n updatedAt: Timestamp;\n}\n\n// ============================================================================\n// CAMPAIGN TYPES\n// ============================================================================\n\n/**\n * Campaign status values\n */\nexport type CampaignStatus = 'active' | 'paused' | 'scheduled' | 'ended';\n\n/**\n * Target platforms for campaigns\n */\nexport type TargetPlatform = 'web' | 'android' | 'ios' | 'extension';\n\n/**\n * Target audience for campaigns\n */\nexport type TargetAudience = 'all' | 'authenticated' | 'anonymous';\n\n/**\n * Placement options for ads\n */\nexport type AdPlacement =\n | 'popup_slider'\n | 'options_panel'\n | 'onetime_modal'\n | 'update_modal'\n | 'notification'\n | 'footer_slider'\n | 'sidebar_panel'\n | 'home_banner';\n\n/**\n * Small panel variant styles\n */\nexport type SmallPanelVariant =\n | 'small_panel_1' // Minimal\n | 'small_panel_2' // Tagline\n | 'small_panel_3' // Features\n | 'small_panel_4' // Gradient\n | 'small_panel_5'; // Card\n\n/**\n * Large slider variant styles\n */\nexport type LargePanelVariant =\n | 'large_slider_1' // Hero\n | 'large_slider_2' // Feature Grid\n | 'large_slider_3' // Testimonial\n | 'large_slider_4' // Comparison\n | 'large_slider_5'; // Video Placeholder\n\n/**\n * All ad variant types\n */\nexport type AdVariant = SmallPanelVariant | LargePanelVariant;\n\n/**\n * Advertising campaign document\n * Stored in: zaions_campaigns/{campaignId}\n */\nexport interface Campaign {\n /** Campaign document ID */\n id: string;\n /** Reference to product being promoted */\n productId: string;\n /** Campaign name (admin reference) */\n name: string;\n /** Current campaign status */\n status: CampaignStatus;\n\n // === TARGETING ===\n /** Platforms where this campaign should show */\n targetPlatforms: TargetPlatform[];\n /** Audience type to target */\n targetAudience: TargetAudience;\n /** Specific projects to target (empty = all projects) */\n targetProjects: string[];\n /** Don't show to users already using this product */\n excludeProductUsers: boolean;\n\n // === DISPLAY RULES ===\n /** Where the ad can be displayed */\n placements: AdPlacement[];\n /** Priority (1-100, higher = more important) */\n priority: number;\n /** Days between impressions for same user (default: 20) */\n frequencyDays: number;\n /** Maximum total impressions (null = unlimited) */\n maxImpressions: number | null;\n\n // === TIMELINE ===\n /** Campaign start date */\n startDate: Timestamp;\n /** Campaign end date (null = no end) */\n endDate: Timestamp | null;\n\n // === CREATIVE ===\n /** UI variant to use */\n variant: AdVariant;\n /** Custom title (overrides product name) */\n customTitle?: string;\n /** Custom tagline (overrides product tagline) */\n customTagline?: string;\n /** Custom CTA button text */\n customCta?: string;\n /** Custom CTA button URL (overrides product URL) */\n customCtaUrl?: string;\n /** Custom description (overrides product description) */\n customDescription?: string;\n /** Custom product color for custom products/projects */\n customProductColor?: string;\n /** Custom icon SVG string (for custom products) */\n customIcon?: string;\n /** Custom features list (for custom products) */\n customFeatures?: string[];\n\n // === METRICS (Denormalized) ===\n /** Total number of impressions */\n totalImpressions: number;\n /** Total number of clicks */\n totalClicks: number;\n /** Total number of closes/dismissals */\n totalCloses: number;\n\n // === METADATA ===\n /** When campaign was created */\n createdAt: Timestamp;\n /** When campaign was last updated */\n updatedAt: Timestamp;\n /** Admin user ID who created */\n createdBy: string;\n /** Admin user ID who last updated */\n updatedBy?: string;\n}\n\n/**\n * Input for creating a new campaign\n */\nexport interface CreateCampaignInput {\n productId: string;\n name: string;\n status: CampaignStatus;\n targetPlatforms: TargetPlatform[];\n targetAudience: TargetAudience;\n targetProjects: string[];\n excludeProductUsers: boolean;\n placements: AdPlacement[];\n priority: number;\n frequencyDays: number;\n maxImpressions: number | null;\n startDate: Date;\n endDate: Date | null;\n variant: AdVariant;\n customTitle?: string;\n customTagline?: string;\n customCta?: string;\n customCtaUrl?: string;\n customDescription?: string;\n customProductColor?: string;\n customIcon?: string;\n customFeatures?: string[];\n}\n\n/**\n * Input for updating a campaign\n */\nexport interface UpdateCampaignInput extends Partial<CreateCampaignInput> {\n id: string;\n}\n\n// ============================================================================\n// IMPRESSION TYPES\n// ============================================================================\n\n/**\n * Types of ad interactions\n */\nexport type AdAction = 'impression' | 'click' | 'close' | 'notification_click';\n\n/**\n * Ad impression/interaction event\n * Stored in: zaions_impressions/{impressionId}\n */\nexport interface Impression {\n /** Impression document ID */\n id: string;\n /** Campaign that generated this impression */\n campaignId: string;\n /** Product being advertised */\n productId: string;\n /** Project where impression occurred */\n projectId: string;\n\n /** User ID (null for anonymous) */\n userId: string | null;\n /** Device/browser fingerprint */\n deviceId: string;\n /** Platform where impression occurred */\n platform: TargetPlatform;\n /** Placement where ad was shown */\n placement: AdPlacement;\n\n /** Type of interaction */\n action: AdAction;\n /** When the interaction occurred */\n timestamp: Timestamp;\n\n /** UI variant that was displayed */\n variant: AdVariant;\n /** Session identifier */\n sessionId?: string;\n}\n\n/**\n * Input for recording an impression\n */\nexport interface RecordImpressionInput {\n campaignId: string;\n productId: string;\n placement: AdPlacement;\n action: AdAction;\n variant: AdVariant;\n sessionId?: string;\n}\n\n// ============================================================================\n// AD HISTORY TYPES\n// ============================================================================\n\n/**\n * Local ad history entry (for frequency capping)\n */\nexport interface AdHistoryEntry {\n /** Campaign ID */\n campaignId: string;\n /** Product ID */\n productId: string;\n /** Last seen timestamp (Unix ms) */\n lastSeenAt: number;\n /** Impression count */\n impressionCount: number;\n /** Whether clicked */\n clicked: boolean;\n /** Whether closed */\n closed: boolean;\n /** Next eligible timestamp (Unix ms) */\n nextEligibleAt: number;\n}\n\n// ============================================================================\n// SERVICE TYPES\n// ============================================================================\n\n/**\n * Options for fetching campaigns\n */\nexport interface FetchCampaignsOptions {\n /** Filter by placement */\n placement?: AdPlacement;\n /** Filter by status */\n status?: CampaignStatus;\n /** Filter by product */\n productId?: string;\n /** Maximum results */\n limit?: number;\n}\n\n/**\n * Campaign with resolved product data\n */\nexport interface CampaignWithProduct extends Campaign {\n /** Resolved product information */\n product: Product;\n}\n\n// ============================================================================\n// ANALYTICS TYPES\n// ============================================================================\n\n/**\n * Campaign analytics summary\n */\nexport interface CampaignAnalytics {\n campaignId: string;\n campaignName: string;\n productId: string;\n productName: string;\n\n /** Total impressions */\n impressions: number;\n /** Total clicks */\n clicks: number;\n /** Total closes */\n closes: number;\n /** Click-through rate (clicks/impressions) */\n ctr: number;\n /** Close rate (closes/impressions) */\n closeRate: number;\n\n /** Breakdown by platform */\n byPlatform: Record<TargetPlatform, { impressions: number; clicks: number }>;\n /** Breakdown by placement */\n byPlacement: Record<AdPlacement, { impressions: number; clicks: number }>;\n /** Breakdown by project */\n byProject: Record<string, { impressions: number; clicks: number }>;\n /** Daily breakdown */\n byDate: Array<{\n date: string;\n impressions: number;\n clicks: number;\n closes: number;\n }>;\n}\n\n// ============================================================================\n// COMPONENT PROPS\n// ============================================================================\n\n/**\n * Props for small panel variant components\n */\nexport interface SmallPanelProps {\n /** Campaign with product data */\n campaign: CampaignWithProduct;\n /** Called when user clicks CTA */\n onCTAClick?: () => void;\n /** Called when user closes/dismisses the ad */\n onClose?: () => void;\n}\n\n/**\n * Props for large panel variant components\n */\nexport interface LargePanelProps {\n /** Campaign with product data */\n campaign: CampaignWithProduct;\n /** Called when user clicks CTA */\n onCTAClick?: () => void;\n /** Called when user closes/dismisses the ad */\n onClose?: () => void;\n /** Whether to show slide indicator */\n showIndicator?: boolean;\n /** Current slide index (for carousel) */\n currentIndex?: number;\n /** Total number of slides (for carousel) */\n totalCount?: number;\n}\n\n/**\n * Props for ad panel component\n */\nexport interface AdPanelProps {\n placement: AdPlacement;\n variant?: SmallPanelVariant;\n className?: string;\n}\n\n// ============================================================================\n// DEFAULT VALUES\n// ============================================================================\n\n/**\n * Default frequency cap in days\n */\nexport const DEFAULT_FREQUENCY_DAYS = 20;\n\n/**\n * Default campaign priority\n */\nexport const DEFAULT_CAMPAIGN_PRIORITY = 50;\n\n/**\n * Variant display names\n */\nexport const VARIANT_NAMES: Record<AdVariant, string> = {\n small_panel_1: 'Minimal',\n small_panel_2: 'Tagline',\n small_panel_3: 'Features',\n small_panel_4: 'Gradient',\n small_panel_5: 'Card',\n large_slider_1: 'Hero',\n large_slider_2: 'Feature Grid',\n large_slider_3: 'Testimonial',\n large_slider_4: 'Comparison',\n large_slider_5: 'Video Placeholder',\n};\n\n/**\n * Placement display names\n */\nexport const PLACEMENT_NAMES: Record<AdPlacement, string> = {\n popup_slider: 'Extension Popup Slider',\n options_panel: 'Extension Options Panel',\n onetime_modal: 'One-Time Welcome Modal',\n update_modal: 'Update Announcement Modal',\n notification: 'Browser Notification',\n footer_slider: 'Web App Footer Slider',\n sidebar_panel: 'Web App Sidebar Panel',\n home_banner: 'Home Page Banner',\n};\n\n/**\n * Platform display names\n */\nexport const PLATFORM_NAMES: Record<TargetPlatform, string> = {\n web: 'Web App',\n android: 'Android App',\n ios: 'iOS App',\n extension: 'Browser Extension',\n};\n\n// ============================================================================\n// FIREBASE COLLECTION NAMES\n// ============================================================================\n\n/**\n * Collection names for shared features\n */\nexport const COLLECTIONS = {\n CAMPAIGNS: 'zaions_campaigns',\n PRODUCTS: 'zaions_products',\n IMPRESSIONS: 'zaions_impressions',\n CONTACTS: 'zaions_contacts',\n FEATURE_REQUESTS: 'zaions_feature_requests',\n PAYMENT_OPTIONS: 'zaions_payment_options',\n SOCIAL_LINKS: 'zaions_social_links',\n DEVELOPER_INFO: 'zaions_developer_info',\n} as const;\n","/**\n * In-App Notification System Type Definitions\n *\n * Type definitions for the unified notification system including\n * broadcasts, user notifications, templates, and preferences.\n *\n * Architecture:\n * - Broadcasts: Stored in shared-features Firebase (zaions_broadcasts)\n * - User notifications: Stored in consumer project's Firebase\n * - Templates: Stored in shared-features Firebase (zaions_notification_templates)\n *\n * @author Ahsan Mahmood <aoneahsan@gmail.com>\n */\n\nimport { Timestamp } from 'firebase/firestore';\n\n// ============================================================================\n// NOTIFICATION CATEGORIES & TYPES\n// ============================================================================\n\n/**\n * Standard notification categories for grouping and filtering\n */\nexport type NotificationCategory =\n | 'system' // Maintenance, updates, outages\n | 'account' // Welcome, security, profile changes\n | 'activity' // CRUD operations, user actions\n | 'report' // Weekly/monthly summaries\n | 'promotional' // Tips, features, holidays\n | 'social'; // Shares, mentions, comments\n\n/**\n * Visual notification type for styling\n */\nexport type NotificationType =\n | 'info' // General information\n | 'success' // Positive feedback\n | 'warning' // Attention needed\n | 'error' // Something went wrong\n | 'reminder' // Time-based reminder\n | 'milestone' // Achievement/progress\n | 'announcement'; // Important announcement\n\n/**\n * Priority levels for notifications\n */\nexport type NotificationPriority = 'urgent' | 'high' | 'normal' | 'low';\n\n/**\n * Source of the notification\n */\nexport type NotificationSource =\n | 'system' // Auto-generated by system\n | 'event' // Triggered by user action\n | 'broadcast' // Cross-project announcement\n | 'admin'; // Sent by admin\n\n/**\n * Broadcast display variants\n */\nexport type BroadcastVariant = 'banner' | 'modal' | 'toast' | 'bell';\n\n/**\n * Broadcast status\n */\nexport type BroadcastStatus = 'draft' | 'scheduled' | 'active' | 'ended';\n\n/**\n * Target platforms for notifications\n */\nexport type NotificationPlatform = 'web' | 'android' | 'ios';\n\n/**\n * Target audience for broadcasts\n */\nexport type NotificationAudience = 'all' | 'authenticated' | 'anonymous';\n\n// ============================================================================\n// STANDARD EVENT TYPES\n// ============================================================================\n\n/**\n * Standard event types that trigger notifications\n */\nexport type StandardEventType =\n // Account Events\n | 'ACCOUNT_CREATED'\n | 'ACCOUNT_WELCOME'\n | 'NEW_DEVICE_SIGNIN'\n | 'PASSWORD_CHANGED'\n | 'PROFILE_UPDATED'\n | 'ACCOUNT_DELETED'\n // Report Events\n | 'DAILY_SUMMARY'\n | 'WEEKLY_SUMMARY'\n | 'MONTHLY_SUMMARY'\n | 'QUARTERLY_SUMMARY'\n | 'YEARLY_SUMMARY'\n // Promotional Events\n | 'APP_TIP'\n | 'HIDDEN_FEATURE'\n | 'NEW_FEATURE_ANNOUNCEMENT'\n | 'HOLIDAY_GREETING'\n // System Events\n | 'SYSTEM_MAINTENANCE'\n | 'APP_UPDATE_AVAILABLE'\n | 'DATA_EXPORT_READY'\n // Activity Events (Generic CRUD)\n | 'ITEM_CREATED'\n | 'ITEM_UPDATED'\n | 'ITEM_DELETED'\n | 'BULK_OPERATION_COMPLETE';\n\n// ============================================================================\n// BASE NOTIFICATION INTERFACE\n// ============================================================================\n\n/**\n * Base notification fields shared across all notification types\n */\nexport interface BaseNotification {\n /** Unique notification ID */\n id: string;\n /** Notification title */\n title: string;\n /** Notification message/body */\n message: string;\n /** Visual type for styling */\n type: NotificationType;\n /** Category for grouping/filtering */\n category: NotificationCategory;\n /** Whether the notification has been read */\n isRead: boolean;\n /** Whether this notification is important/pinned */\n isImportant?: boolean;\n /** Optional action URL to navigate to */\n actionUrl?: string;\n /** Optional action button text */\n actionText?: string;\n /** When the notification was created */\n createdAt: Date | Timestamp;\n /** When the notification was read */\n readAt?: Date | Timestamp;\n /** Additional metadata for custom use */\n metadata?: Record<string, unknown>;\n}\n\n// ============================================================================\n// USER NOTIFICATION\n// ============================================================================\n\n/**\n * User-specific notification stored in consumer project's Firebase\n * Collection: {prefix}_notifications/{notificationId}\n */\nexport interface UserNotification extends BaseNotification {\n /** User ID this notification belongs to */\n userId: string;\n /** How the notification was generated */\n source: NotificationSource;\n /** Reference to source entity (broadcast ID, event ID, etc.) */\n sourceId?: string;\n /** Event type if triggered by event */\n eventType?: StandardEventType | string;\n /** When the notification expires (auto-delete) */\n expiresAt?: Date | Timestamp;\n}\n\n/**\n * Input for creating a user notification\n */\nexport interface CreateUserNotificationInput {\n userId: string;\n title: string;\n message: string;\n type: NotificationType;\n category: NotificationCategory;\n source: NotificationSource;\n sourceId?: string;\n eventType?: StandardEventType | string;\n isImportant?: boolean;\n actionUrl?: string;\n actionText?: string;\n expiresAt?: Date;\n metadata?: Record<string, unknown>;\n}\n\n// ============================================================================\n// BROADCAST NOTIFICATION\n// ============================================================================\n\n/**\n * Cross-project broadcast notification stored in shared-features Firebase\n * Collection: zaions_broadcasts/{broadcastId}\n */\nexport interface BroadcastNotification extends BaseNotification {\n /** Target project IDs (empty = all projects) */\n targetProjects: string[];\n /** Target platforms */\n targetPlatforms: NotificationPlatform[];\n /** Target audience */\n targetAudience: NotificationAudience;\n /** Broadcast status */\n status: BroadcastStatus;\n /** When the broadcast becomes active */\n startDate: Date | Timestamp;\n /** When the broadcast ends (null = no end) */\n endDate?: Date | Timestamp | null;\n /** Display priority (1-100, higher = more important) */\n priority: number;\n /** Whether user can dismiss this broadcast */\n dismissible: boolean;\n /** How to display this broadcast */\n variant: BroadcastVariant;\n /** Total impressions count */\n impressions: number;\n /** Total clicks count */\n clicks: number;\n /** Admin user ID who created */\n createdBy: string;\n /** Admin user ID who last updated */\n updatedBy?: string;\n}\n\n/**\n * Input for creating a broadcast\n */\nexport interface CreateBroadcastInput {\n title: string;\n message: string;\n type: NotificationType;\n category: NotificationCategory;\n targetProjects: string[];\n targetPlatforms: NotificationPlatform[];\n targetAudience: NotificationAudience;\n startDate: Date;\n endDate?: Date | null;\n priority: number;\n dismissible: boolean;\n variant: BroadcastVariant;\n isImportant?: boolean;\n actionUrl?: string;\n actionText?: string;\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Input for updating a broadcast\n */\nexport interface UpdateBroadcastInput extends Partial<CreateBroadcastInput> {\n id: string;\n status?: BroadcastStatus;\n}\n\n// ============================================================================\n// NOTIFICATION TEMPLATE\n// ============================================================================\n\n/**\n * Notification template for standard events\n * Collection: zaions_notification_templates/{templateId}\n */\nexport interface NotificationTemplate {\n /** Template ID */\n id: string;\n /** Template name for admin reference */\n name: string;\n /** Event type this template is for */\n eventType: StandardEventType | string;\n /** Notification category */\n category: NotificationCategory;\n /** Title with placeholders: \"Welcome to {{appName}}, {{userName}}!\" */\n title: string;\n /** Message with placeholders */\n message: string;\n /** List of variable names used in title/message */\n variables: string[];\n /** Visual notification type */\n type: NotificationType;\n /** Whether notifications from this template are important */\n isImportant: boolean;\n /** Default action URL (can use placeholders) */\n actionUrl?: string;\n /** Default action button text */\n actionText?: string;\n /** Whether this template is enabled */\n enabled: boolean;\n /** When template was created */\n createdAt: Date | Timestamp;\n /** When template was last updated */\n updatedAt: Date | Timestamp;\n}\n\n/**\n * Input for creating a template\n */\nexport interface CreateTemplateInput {\n name: string;\n eventType: StandardEventType | string;\n category: NotificationCategory;\n title: string;\n message: string;\n variables: string[];\n type: NotificationType;\n isImportant: boolean;\n actionUrl?: string;\n actionText?: string;\n enabled: boolean;\n}\n\n// ============================================================================\n// USER NOTIFICATION PREFERENCES\n// ============================================================================\n\n/**\n * Category preference settings\n */\nexport interface CategoryPreference {\n /** Show in-app notifications for this category */\n inApp: boolean;\n /** Send push notifications for this category */\n push: boolean;\n /** Send email notifications for this category */\n email: boolean;\n}\n\n/**\n * Quiet hours configuration\n */\nexport interface QuietHoursConfig {\n /** Whether quiet hours are enabled */\n enabled: boolean;\n /** Start time in 24h format: \"22:00\" */\n start: string;\n /** End time in 24h format: \"08:00\" */\n end: string;\n /** User's timezone (IANA format) */\n timezone: string;\n}\n\n/**\n * Email digest configuration\n */\nexport interface EmailDigestConfig {\n /** Whether email digest is enabled */\n enabled: boolean;\n /** Digest frequency */\n frequency: 'daily' | 'weekly' | 'none';\n}\n\n/**\n * Push notification configuration\n */\nexport interface PushConfig {\n /** Whether push is enabled */\n enabled: boolean;\n /** OneSignal player ID */\n playerId?: string;\n /** Web push subscription */\n webPushSubscription?: PushSubscription;\n}\n\n/**\n * User notification preferences\n * Collection: {prefix}_notification_preferences/{userId}\n */\nexport interface NotificationPreferences {\n /** User ID */\n userId: string;\n /** Category-specific preferences */\n categories: Record<NotificationCategory, CategoryPreference>;\n /** Quiet hours settings */\n quietHours: QuietHoursConfig;\n /** Email digest settings */\n emailDigest: EmailDigestConfig;\n /** Push notification settings */\n push: PushConfig;\n /** When preferences were last updated */\n updatedAt: Date | Timestamp;\n}\n\n/**\n * Default notification preferences\n */\nexport const DEFAULT_NOTIFICATION_PREFERENCES: Omit<\n NotificationPreferences,\n 'userId' | 'updatedAt'\n> = {\n categories: {\n system: { inApp: true, push: true, email: false },\n account: { inApp: true, push: true, email: true },\n activity: { inApp: true, push: false, email: false },\n report: { inApp: true, push: false, email: true },\n promotional: { inApp: true, push: false, email: false },\n social: { inApp: true, push: true, email: false },\n },\n quietHours: {\n enabled: false,\n start: '22:00',\n end: '08:00',\n timezone: 'UTC',\n },\n emailDigest: {\n enabled: false,\n frequency: 'none',\n },\n push: {\n enabled: false,\n },\n};\n\n// ============================================================================\n// NOTIFICATION EVENTS\n// ============================================================================\n\n/**\n * Event definition for triggering notifications\n */\nexport interface NotificationEventDefinition {\n /** Event type identifier */\n type: StandardEventType | string;\n /** Event display name */\n name: string;\n /** Event description */\n description: string;\n /** Default notification category */\n category: NotificationCategory;\n /** Default notification type */\n notificationType: NotificationType;\n /** Default priority */\n priority: NotificationPriority;\n /** Available template variables */\n variables: string[];\n /** Whether this event is enabled by default */\n defaultEnabled: boolean;\n}\n\n/**\n * Event trigger payload\n */\nexport interface NotificationEventPayload {\n /** Event type */\n type: StandardEventType | string;\n /** User ID to notify */\n userId: string;\n /** Variable values for template interpolation */\n data: Record<string, string | number | boolean>;\n /** Optional override for notification title */\n titleOverride?: string;\n /** Optional override for notification message */\n messageOverride?: string;\n /** Optional action URL */\n actionUrl?: string;\n /** Optional action text */\n actionText?: string;\n /** Additional metadata */\n metadata?: Record<string, unknown>;\n}\n\n// ============================================================================\n// ANALYTICS TYPES\n// ============================================================================\n\n/**\n * Broadcast analytics summary\n */\nexport interface BroadcastAnalytics {\n broadcastId: string;\n title: string;\n status: BroadcastStatus;\n impressions: number;\n clicks: number;\n dismissals: number;\n ctr: number;\n byPlatform: Record<NotificationPlatform, { impressions: number; clicks: number }>;\n byProject: Record<string, { impressions: number; clicks: number }>;\n byDate: Array<{\n date: string;\n impressions: number;\n clicks: number;\n }>;\n}\n\n/**\n * Overall notification analytics\n */\nexport interface NotificationAnalytics {\n /** Total notifications sent */\n totalSent: number;\n /** Total notifications read */\n totalRead: number;\n /** Total notifications clicked */\n totalClicked: number;\n /** Read rate (read/sent) */\n readRate: number;\n /** Click rate (clicked/sent) */\n clickRate: number;\n /** Breakdown by category */\n byCategory: Record<\n NotificationCategory,\n {\n sent: number;\n read: number;\n clicked: number;\n }\n >;\n /** Breakdown by type */\n byType: Record<\n NotificationType,\n {\n sent: number;\n read: number;\n clicked: number;\n }\n >;\n /** Daily breakdown */\n byDate: Array<{\n date: string;\n sent: number;\n read: number;\n clicked: number;\n }>;\n}\n\n// ============================================================================\n// COMPONENT PROPS\n// ============================================================================\n\n/**\n * Props for NotificationBell component\n */\nexport interface NotificationBellProps {\n /** Additional CSS classes */\n className?: string;\n /** Icon size in pixels */\n size?: number;\n /** Show count badge even when 0 */\n showZeroBadge?: boolean;\n /** Custom onClick handler (default: toggle panel) */\n onClick?: () => void;\n}\n\n/**\n * Props for NotificationPanel component\n */\nexport interface NotificationPanelProps {\n /** Whether the panel is open */\n isOpen: boolean;\n /** Called when panel should close */\n onClose: () => void;\n /** Maximum height for the panel */\n maxHeight?: string;\n /** Whether to show the filter tabs */\n showFilters?: boolean;\n /** Custom empty state component */\n emptyStateComponent?: React.ReactNode;\n}\n\n/**\n * Props for NotificationCard component\n */\nexport interface NotificationCardProps {\n /** The notification to display */\n notification: UserNotification;\n /** Called when notification is clicked */\n onClick?: () => void;\n /** Called when delete button is clicked */\n onDelete?: () => void;\n /** Whether to show delete button */\n showDelete?: boolean;\n /** Whether to show timestamp */\n showTimestamp?: boolean;\n}\n\n/**\n * Props for BroadcastBanner component\n */\nexport interface BroadcastBannerProps {\n /** The broadcast to display */\n broadcast: BroadcastNotification;\n /** Called when CTA is clicked */\n onActionClick?: () => void;\n /** Called when banner is dismissed */\n onDismiss?: () => void;\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Props for AnnouncementModal component\n */\nexport interface AnnouncementModalProps {\n /** The broadcast to display */\n broadcast: BroadcastNotification;\n /** Whether the modal is open */\n isOpen: boolean;\n /** Called when modal should close */\n onClose: () => void;\n /** Called when CTA is clicked */\n onActionClick?: () => void;\n}\n\n/**\n * Props for NotificationPreferences component\n */\nexport interface NotificationPreferencesProps {\n /** Current preferences */\n preferences: NotificationPreferences;\n /** Called when preferences change */\n onPreferencesChange: (preferences: NotificationPreferences) => void;\n /** Whether saving is in progress */\n isSaving?: boolean;\n /** Categories to show (default: all) */\n visibleCategories?: NotificationCategory[];\n /** Whether to show push settings */\n showPushSettings?: boolean;\n /** Whether to show email settings */\n showEmailSettings?: boolean;\n /** Whether to show quiet hours settings */\n showQuietHours?: boolean;\n}\n\n// ============================================================================\n// HOOK RETURN TYPES\n// ============================================================================\n\n/**\n * Return type for useNotifications hook\n */\nexport interface UseNotificationsReturn {\n /** List of notifications */\n notifications: UserNotification[];\n /** Number of unread notifications */\n unreadCount: number;\n /** Whether notifications are loading */\n isLoading: boolean;\n /** Error if any */\n error: Error | null;\n /** Mark a notification as read */\n markAsRead: (notificationId: string) => Promise<void>;\n /** Mark all notifications as read */\n markAllAsRead: () => Promise<void>;\n /** Delete a notification */\n deleteNotification: (notificationId: string) => Promise<void>;\n /** Clear all notifications */\n clearAll: () => Promise<void>;\n /** Refresh notifications */\n refresh: () => Promise<void>;\n}\n\n/**\n * Return type for useBroadcasts hook\n */\nexport interface UseBroadcastsReturn {\n /** List of active broadcasts */\n broadcasts: BroadcastNotification[];\n /** Whether broadcasts are loading */\n isLoading: boolean;\n /** Error if any */\n error: Error | null;\n /** Dismiss a broadcast */\n dismissBroadcast: (broadcastId: string) => void;\n /** Track broadcast impression */\n trackImpression: (broadcastId: string) => void;\n /** Track broadcast click */\n trackClick: (broadcastId: string) => void;\n /** Check if broadcast was dismissed */\n isDismissed: (broadcastId: string) => boolean;\n /** Refresh broadcasts from cache */\n refresh: () => Promise<void>;\n}\n\n/**\n * Return type for useNotificationEvents hook\n */\nexport interface UseNotificationEventsReturn {\n /** Trigger a notification event */\n trigger: (payload: NotificationEventPayload) => Promise<void>;\n /** Trigger account created event */\n triggerAccountCreated: (data: { userName: string; email: string }) => Promise<void>;\n /** Trigger new device signin event */\n triggerNewDeviceSignin: (data: { deviceName: string; location?: string }) => Promise<void>;\n /** Trigger password changed event */\n triggerPasswordChanged: () => Promise<void>;\n /** Trigger profile updated event */\n triggerProfileUpdated: (data: { changes: string[] }) => Promise<void>;\n /** Trigger CRUD event */\n triggerCrudEvent: (data: {\n action: 'created' | 'updated' | 'deleted';\n entityType: string;\n entityName: string;\n }) => Promise<void>;\n /** Trigger app tip event */\n triggerAppTip: (data: { tipId: string; title: string; body: string }) => Promise<void>;\n}\n\n// ============================================================================\n// SERVICE TYPES\n// ============================================================================\n\n/**\n * Options for fetching broadcasts\n */\nexport interface FetchBroadcastsOptions {\n /** Filter by project ID */\n projectId?: string;\n /** Filter by platform */\n platform?: NotificationPlatform;\n /** Filter by variant */\n variant?: BroadcastVariant;\n /** Filter by status */\n status?: BroadcastStatus;\n /** Maximum results */\n limit?: number;\n}\n\n/**\n * Options for fetching user notifications\n */\nexport interface FetchNotificationsOptions {\n /** User ID */\n userId: string;\n /** Filter by category */\n category?: NotificationCategory;\n /** Filter by read status */\n isRead?: boolean;\n /** Maximum results */\n limit?: number;\n /** Offset for pagination */\n offset?: number;\n /** Start date filter */\n startDate?: Date;\n /** End date filter */\n endDate?: Date;\n}\n\n// ============================================================================\n// COLLECTION NAMES\n// ============================================================================\n\n/**\n * Shared collections (stored in shared-features Firebase)\n */\nexport const NOTIFICATION_COLLECTIONS = {\n /** Cross-project broadcasts */\n BROADCASTS: 'zaions_broadcasts',\n /** Notification templates */\n TEMPLATES: 'zaions_notification_templates',\n /** Broadcast events/analytics */\n BROADCAST_EVENTS: 'zaions_broadcast_events',\n} as const;\n\n/**\n * Get consumer project collection names\n * @param prefix - Project prefix (e.g., 'pp' for pregnancy-pal)\n */\nexport const getNotificationCollections = (prefix: string) =>\n ({\n /** User notifications */\n NOTIFICATIONS: `${prefix}_notifications`,\n /** User notification preferences */\n PREFERENCES: `${prefix}_notification_preferences`,\n /** Push subscriptions */\n PUSH_SUBSCRIPTIONS: `${prefix}_push_subscriptions`,\n }) as const;\n\n// ============================================================================\n// DISPLAY NAMES & CONSTANTS\n// ============================================================================\n\n/**\n * Category display names\n */\nexport const CATEGORY_NAMES: Record<NotificationCategory, string> = {\n system: 'System',\n account: 'Account',\n activity: 'Activity',\n report: 'Reports',\n promotional: 'Tips & Updates',\n social: 'Social',\n};\n\n/**\n * Category descriptions\n */\nexport const CATEGORY_DESCRIPTIONS: Record<NotificationCategory, string> = {\n system: 'Maintenance updates, outages, and system alerts',\n account: 'Welcome messages, security alerts, and profile changes',\n activity: 'Updates about your actions and changes',\n report: 'Weekly and monthly summaries of your activity',\n promotional: 'Tips, new features, and holiday greetings',\n social: 'Mentions, shares, and comments from others',\n};\n\n/**\n * Notification type display names\n */\nexport const TYPE_NAMES: Record<NotificationType, string> = {\n info: 'Information',\n success: 'Success',\n warning: 'Warning',\n error: 'Error',\n reminder: 'Reminder',\n milestone: 'Milestone',\n announcement: 'Announcement',\n};\n\n/**\n * Priority display names\n */\nexport const PRIORITY_NAMES: Record<NotificationPriority, string> = {\n urgent: 'Urgent',\n high: 'High',\n normal: 'Normal',\n low: 'Low',\n};\n\n/**\n * Event type display names\n */\nexport const EVENT_TYPE_NAMES: Record<StandardEventType, string> = {\n ACCOUNT_CREATED: 'Account Created',\n ACCOUNT_WELCOME: 'Welcome Message',\n NEW_DEVICE_SIGNIN: 'New Device Sign-in',\n PASSWORD_CHANGED: 'Password Changed',\n PROFILE_UPDATED: 'Profile Updated',\n ACCOUNT_DELETED: 'Account Deleted',\n DAILY_SUMMARY: 'Daily Summary',\n WEEKLY_SUMMARY: 'Weekly Summary',\n MONTHLY_SUMMARY: 'Monthly Summary',\n QUARTERLY_SUMMARY: 'Quarterly Summary',\n YEARLY_SUMMARY: 'Yearly Summary',\n APP_TIP: 'App Tip',\n HIDDEN_FEATURE: 'Hidden Feature',\n NEW_FEATURE_ANNOUNCEMENT: 'New Feature',\n HOLIDAY_GREETING: 'Holiday Greeting',\n SYSTEM_MAINTENANCE: 'System Maintenance',\n APP_UPDATE_AVAILABLE: 'App Update Available',\n DATA_EXPORT_READY: 'Data Export Ready',\n ITEM_CREATED: 'Item Created',\n ITEM_UPDATED: 'Item Updated',\n ITEM_DELETED: 'Item Deleted',\n BULK_OPERATION_COMPLETE: 'Bulk Operation Complete',\n};\n\n/**\n * Default broadcast priority\n */\nexport const DEFAULT_BROADCAST_PRIORITY = 50;\n\n/**\n * Maximum notification title length\n */\nexport const MAX_NOTIFICATION_TITLE_LENGTH = 100;\n\n/**\n * Maximum notification message length\n */\nexport const MAX_NOTIFICATION_MESSAGE_LENGTH = 500;\n"],"names":[],"mappings":"AA2aO,MAAM,yBAAyB;AAK/B,MAAM,4BAA4B;AAKlC,MAAM,gBAA2C;AAAA,EACtD,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,gBAAgB;AAClB;AAKO,MAAM,kBAA+C;AAAA,EAC1D,cAAc;AAAA,EACd,eAAe;AAAA,EACf,eAAe;AAAA,EACf,cAAc;AAAA,EACd,cAAc;AAAA,EACd,eAAe;AAAA,EACf,eAAe;AAAA,EACf,aAAa;AACf;AAKO,MAAM,iBAAiD;AAAA,EAC5D,KAAK;AAAA,EACL,SAAS;AAAA,EACT,KAAK;AAAA,EACL,WAAW;AACb;AASO,MAAM,cAAc;AAAA,EACzB,WAAW;AAAA,EACX,UAAU;AAAA,EACV,aAAa;AAAA,EACb,UAAU;AAAA,EACV,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,cAAc;AAAA,EACd,gBAAgB;AAClB;AC1GO,MAAM,mCAGT;AAAA,EACF,YAAY;AAAA,IACV,QAAQ,EAAE,OAAO,MAAM,MAAM,MAAM,OAAO,MAAA;AAAA,IAC1C,SAAS,EAAE,OAAO,MAAM,MAAM,MAAM,OAAO,KAAA;AAAA,IAC3C,UAAU,EAAE,OAAO,MAAM,MAAM,OAAO,OAAO,MAAA;AAAA,IAC7C,QAAQ,EAAE,OAAO,MAAM,MAAM,OAAO,OAAO,KAAA;AAAA,IAC3C,aAAa,EAAE,OAAO,MAAM,MAAM,OAAO,OAAO,MAAA;AAAA,IAChD,QAAQ,EAAE,OAAO,MAAM,MAAM,MAAM,OAAO,MAAA;AAAA,EAAM;AAAA,EAElD,YAAY;AAAA,IACV,SAAS;AAAA,IACT,OAAO;AAAA,IACP,KAAK;AAAA,IACL,UAAU;AAAA,EAAA;AAAA,EAEZ,aAAa;AAAA,IACX,SAAS;AAAA,IACT,WAAW;AAAA,EAAA;AAAA,EAEb,MAAM;AAAA,IACJ,SAAS;AAAA,EAAA;AAEb;AA8UO,MAAM,2BAA2B;AAAA;AAAA,EAEtC,YAAY;AAAA;AAAA,EAEZ,WAAW;AAAA;AAAA,EAEX,kBAAkB;AACpB;AAMO,MAAM,6BAA6B,CAAC,YACxC;AAAA;AAAA,EAEC,eAAe,GAAG,MAAM;AAAA;AAAA,EAExB,aAAa,GAAG,MAAM;AAAA;AAAA,EAEtB,oBAAoB,GAAG,MAAM;AAC/B;AASK,MAAM,iBAAuD;AAAA,EAClE,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,QAAQ;AACV;AAKO,MAAM,wBAA8D;AAAA,EACzE,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,QAAQ;AACV;AAKO,MAAM,aAA+C;AAAA,EAC1D,MAAM;AAAA,EACN,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AAAA,EACP,UAAU;AAAA,EACV,WAAW;AAAA,EACX,cAAc;AAChB;AAKO,MAAM,iBAAuD;AAAA,EAClE,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,KAAK;AACP;AAKO,MAAM,mBAAsD;AAAA,EACjE,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,gBAAgB;AAAA,EAChB,SAAS;AAAA,EACT,gBAAgB;AAAA,EAChB,0BAA0B;AAAA,EAC1B,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,mBAAmB;AAAA,EACnB,cAAc;AAAA,EACd,cAAc;AAAA,EACd,cAAc;AAAA,EACd,yBAAyB;AAC3B;AAKO,MAAM,6BAA6B;AAKnC,MAAM,gCAAgC;AAKtC,MAAM,kCAAkC;"}
|