shared-features 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +84 -7
  2. package/dist/AdBanner-B9918Vst.cjs +1427 -0
  3. package/dist/AdBanner-B9918Vst.cjs.map +1 -0
  4. package/dist/AdBanner-z1osYgog.js +1428 -0
  5. package/dist/AdBanner-z1osYgog.js.map +1 -0
  6. package/dist/components/ads/AdBanner.d.ts +25 -0
  7. package/dist/components/ads/AdBanner.d.ts.map +1 -0
  8. package/dist/components/ads/AdModal.d.ts +27 -0
  9. package/dist/components/ads/AdModal.d.ts.map +1 -0
  10. package/dist/components/ads/AdSlider.d.ts +21 -0
  11. package/dist/components/ads/AdSlider.d.ts.map +1 -0
  12. package/dist/components/ads/AdUpdateModal.d.ts +27 -0
  13. package/dist/components/ads/AdUpdateModal.d.ts.map +1 -0
  14. package/dist/components/ads/index.d.ts +9 -0
  15. package/dist/components/ads/index.d.ts.map +1 -1
  16. package/dist/components/ads/variants/LargePanelVariants.d.ts +34 -0
  17. package/dist/components/ads/variants/LargePanelVariants.d.ts.map +1 -0
  18. package/dist/components/ads/variants/SmallPanelVariants.d.ts +34 -0
  19. package/dist/components/ads/variants/SmallPanelVariants.d.ts.map +1 -0
  20. package/dist/components/ads/variants/index.d.ts +12 -0
  21. package/dist/components/ads/variants/index.d.ts.map +1 -0
  22. package/dist/components/index.cjs +20 -2
  23. package/dist/components/index.cjs.map +1 -1
  24. package/dist/components/index.js +20 -2
  25. package/dist/hooks/index.cjs +3 -1
  26. package/dist/hooks/index.cjs.map +1 -1
  27. package/dist/hooks/index.d.ts +1 -1
  28. package/dist/hooks/index.d.ts.map +1 -1
  29. package/dist/hooks/index.js +4 -2
  30. package/dist/hooks/useCampaigns.d.ts +44 -0
  31. package/dist/hooks/useCampaigns.d.ts.map +1 -1
  32. package/dist/index.cjs +23 -3
  33. package/dist/index.cjs.map +1 -1
  34. package/dist/index.js +23 -3
  35. package/dist/types/campaigns.d.ts +20 -32
  36. package/dist/types/campaigns.d.ts.map +1 -1
  37. package/dist/types/index.cjs.map +1 -1
  38. package/dist/types/index.js.map +1 -1
  39. package/dist/{useCampaigns-BNOHpETm.cjs → useCampaigns-BKGqKAUo.cjs} +56 -1
  40. package/dist/useCampaigns-BKGqKAUo.cjs.map +1 -0
  41. package/dist/{useCampaigns-3NxODLLs.js → useCampaigns-osYDc6WC.js} +56 -1
  42. package/dist/{useCampaigns-3NxODLLs.js.map → useCampaigns-osYDc6WC.js.map} +1 -1
  43. package/package.json +3 -1
  44. package/dist/AdPanel-D0BiV6Xb.cjs +0 -88
  45. package/dist/AdPanel-D0BiV6Xb.cjs.map +0 -1
  46. package/dist/AdPanel-RGRBf4ub.js +0 -89
  47. package/dist/AdPanel-RGRBf4ub.js.map +0 -1
  48. package/dist/useCampaigns-BNOHpETm.cjs.map +0 -1
@@ -56,4 +56,48 @@ export declare function useCampaigns(options: UseCampaignsOptions): UseCampaigns
56
56
  * Convenience wrapper around useCampaigns
57
57
  */
58
58
  export declare function useCampaign(options: Omit<UseCampaignsOptions, 'maxCampaigns'>): UseCampaignsResult;
59
+ /**
60
+ * Hook to manage one-time ad modal visibility
61
+ * Shows modal on first visit, then remembers user has seen it
62
+ *
63
+ * @example
64
+ * ```tsx
65
+ * const { shouldShow, markAsShown } = useOneTimeAdModal();
66
+ *
67
+ * if (shouldShow) {
68
+ * return <AdModal onClose={markAsShown} />;
69
+ * }
70
+ * ```
71
+ */
72
+ export declare function useOneTimeAdModal(): {
73
+ /** Whether the modal should be displayed */
74
+ shouldShow: boolean;
75
+ /** Mark the modal as shown (call when user dismisses) */
76
+ markAsShown: () => void;
77
+ };
78
+ /**
79
+ * Hook to manage update ad modal visibility
80
+ * Shows modal when app version changes
81
+ *
82
+ * @param currentVersion - Current app version (defaults to VITE_APP_VERSION env var or '1.0.0')
83
+ *
84
+ * @example
85
+ * ```tsx
86
+ * const { shouldShow, currentVersion, markAsShown } = useUpdateAdModal();
87
+ *
88
+ * if (shouldShow) {
89
+ * return <AdUpdateModal version={currentVersion} onClose={markAsShown} />;
90
+ * }
91
+ * ```
92
+ */
93
+ export declare function useUpdateAdModal(currentVersion?: string): {
94
+ /** Whether the modal should be displayed */
95
+ shouldShow: boolean;
96
+ /** Previous app version (before update) */
97
+ previousVersion: string | null;
98
+ /** Current app version */
99
+ currentVersion: string;
100
+ /** Mark the modal as shown (call when user dismisses) */
101
+ markAsShown: () => void;
102
+ };
59
103
  //# sourceMappingURL=useCampaigns.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useCampaigns.d.ts","sourceRoot":"","sources":["../../src/hooks/useCampaigns.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAWH,OAAO,KAAK,EACV,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,mBAAmB;IAClC,uCAAuC;IACvC,SAAS,EAAE,WAAW,CAAC;IACvB,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,2CAA2C;IAC3C,mBAAmB,CAAC,EAAE,iBAAiB,CAAC;IACxC,2CAA2C;IAC3C,mBAAmB,CAAC,EAAE,iBAAiB,CAAC;CACzC;AAED,MAAM,WAAW,kBAAkB;IACjC,mDAAmD;IACnD,SAAS,EAAE,mBAAmB,EAAE,CAAC;IACjC,8DAA8D;IAC9D,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACrC,0CAA0C;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,oCAAoC;IACpC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,wBAAwB;IACxB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,uCAAuC;IACvC,gBAAgB,EAAE,CAAC,QAAQ,EAAE,mBAAmB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,kCAAkC;IAClC,WAAW,EAAE,CAAC,QAAQ,EAAE,mBAAmB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D,0CAA0C;IAC1C,WAAW,EAAE,CAAC,QAAQ,EAAE,mBAAmB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/D;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,kBAAkB,CAgH7E;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,mBAAmB,EAAE,cAAc,CAAC,sBAE7E"}
1
+ {"version":3,"file":"useCampaigns.d.ts","sourceRoot":"","sources":["../../src/hooks/useCampaigns.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAWH,OAAO,KAAK,EACV,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,mBAAmB;IAClC,uCAAuC;IACvC,SAAS,EAAE,WAAW,CAAC;IACvB,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,2CAA2C;IAC3C,mBAAmB,CAAC,EAAE,iBAAiB,CAAC;IACxC,2CAA2C;IAC3C,mBAAmB,CAAC,EAAE,iBAAiB,CAAC;CACzC;AAED,MAAM,WAAW,kBAAkB;IACjC,mDAAmD;IACnD,SAAS,EAAE,mBAAmB,EAAE,CAAC;IACjC,8DAA8D;IAC9D,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACrC,0CAA0C;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,oCAAoC;IACpC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,wBAAwB;IACxB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,uCAAuC;IACvC,gBAAgB,EAAE,CAAC,QAAQ,EAAE,mBAAmB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,kCAAkC;IAClC,WAAW,EAAE,CAAC,QAAQ,EAAE,mBAAmB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D,0CAA0C;IAC1C,WAAW,EAAE,CAAC,QAAQ,EAAE,mBAAmB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/D;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,kBAAkB,CAgH7E;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,mBAAmB,EAAE,cAAc,CAAC,sBAE7E;AAQD;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB;IAmB7B,4CAA4C;;IAE5C,yDAAyD;;EAG5D;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,cAAc,CAAC,EAAE,MAAM;IAwBpD,4CAA4C;;IAE5C,2CAA2C;;IAE3C,0BAA0B;;IAE1B,yDAAyD;;EAG5D"}
package/dist/index.cjs CHANGED
@@ -2,8 +2,8 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const analytics = require("./analytics-6shJHRZG.cjs");
4
4
  const types_index = require("./types/index.cjs");
5
- const useCampaigns = require("./useCampaigns-BNOHpETm.cjs");
6
- const AdPanel = require("./AdPanel-D0BiV6Xb.cjs");
5
+ const useCampaigns = require("./useCampaigns-BKGqKAUo.cjs");
6
+ const AdBanner = require("./AdBanner-B9918Vst.cjs");
7
7
  exports.clearCampaignsCache = analytics.clearCampaignsCache;
8
8
  exports.clearProductsCache = analytics.clearProductsCache;
9
9
  exports.fetchActiveCampaigns = analytics.fetchActiveCampaigns;
@@ -33,5 +33,25 @@ exports.PLATFORM_NAMES = types_index.PLATFORM_NAMES;
33
33
  exports.VARIANT_NAMES = types_index.VARIANT_NAMES;
34
34
  exports.useCampaign = useCampaigns.useCampaign;
35
35
  exports.useCampaigns = useCampaigns.useCampaigns;
36
- exports.AdPanel = AdPanel.AdPanel;
36
+ exports.useOneTimeAdModal = useCampaigns.useOneTimeAdModal;
37
+ exports.useUpdateAdModal = useCampaigns.useUpdateAdModal;
38
+ exports.AdBanner = AdBanner.AdBanner;
39
+ exports.AdModal = AdBanner.AdModal;
40
+ exports.AdPanel = AdBanner.AdPanel;
41
+ exports.AdSlider = AdBanner.AdSlider;
42
+ exports.AdUpdateModal = AdBanner.AdUpdateModal;
43
+ exports.CardVariant = AdBanner.CardVariant;
44
+ exports.ComparisonVariant = AdBanner.ComparisonVariant;
45
+ exports.FeatureGridVariant = AdBanner.FeatureGridVariant;
46
+ exports.FeaturesVariant = AdBanner.FeaturesVariant;
47
+ exports.GradientVariant = AdBanner.GradientVariant;
48
+ exports.HeroVariant = AdBanner.HeroVariant;
49
+ exports.LARGE_PANEL_VARIANTS = AdBanner.LARGE_PANEL_VARIANTS;
50
+ exports.MinimalVariant = AdBanner.MinimalVariant;
51
+ exports.SMALL_PANEL_VARIANTS = AdBanner.SMALL_PANEL_VARIANTS;
52
+ exports.TaglineVariant = AdBanner.TaglineVariant;
53
+ exports.TestimonialVariant = AdBanner.TestimonialVariant;
54
+ exports.VideoVariant = AdBanner.VideoVariant;
55
+ exports.getLargePanelVariant = AdBanner.getLargePanelVariant;
56
+ exports.getSmallPanelVariant = AdBanner.getSmallPanelVariant;
37
57
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/dist/index.js CHANGED
@@ -1,15 +1,31 @@
1
1
  import { m, n, h, f, k, j, u, d, c, s, l, g, b, a, i, q, e, r, o, p, t } from "./analytics-Bbmodnm_.js";
2
2
  import { COLLECTIONS, DEFAULT_CAMPAIGN_PRIORITY, DEFAULT_FREQUENCY_DAYS, PLACEMENT_NAMES, PLATFORM_NAMES, VARIANT_NAMES } from "./types/index.js";
3
- import { a as a2, u as u2 } from "./useCampaigns-3NxODLLs.js";
4
- import { A } from "./AdPanel-RGRBf4ub.js";
3
+ import { a as a2, u as u2, b as b2, c as c2 } from "./useCampaigns-osYDc6WC.js";
4
+ import { d as d2, b as b3, A, a as a3, c as c3, C, h as h2, e as e2, F, G, H, L, M, S, T, f as f2, V, i as i2, g as g2 } from "./AdBanner-z1osYgog.js";
5
5
  export {
6
+ d2 as AdBanner,
7
+ b3 as AdModal,
6
8
  A as AdPanel,
9
+ a3 as AdSlider,
10
+ c3 as AdUpdateModal,
7
11
  COLLECTIONS,
12
+ C as CardVariant,
13
+ h2 as ComparisonVariant,
8
14
  DEFAULT_CAMPAIGN_PRIORITY,
9
15
  DEFAULT_FREQUENCY_DAYS,
16
+ e2 as FeatureGridVariant,
17
+ F as FeaturesVariant,
18
+ G as GradientVariant,
19
+ H as HeroVariant,
20
+ L as LARGE_PANEL_VARIANTS,
21
+ M as MinimalVariant,
10
22
  PLACEMENT_NAMES,
11
23
  PLATFORM_NAMES,
24
+ S as SMALL_PANEL_VARIANTS,
25
+ T as TaglineVariant,
26
+ f2 as TestimonialVariant,
12
27
  VARIANT_NAMES,
28
+ V as VideoVariant,
13
29
  m as clearCampaignsCache,
14
30
  n as clearProductsCache,
15
31
  h as fetchActiveCampaigns,
@@ -20,10 +36,12 @@ export {
20
36
  d as getConfig,
21
37
  c as getDeviceId,
22
38
  s as getEligibleCampaignIds,
39
+ i2 as getLargePanelVariant,
23
40
  l as getProductById,
24
41
  g as getSharedFeaturesApp,
25
42
  b as getSharedFeaturesAuth,
26
43
  a as getSharedFeaturesDb,
44
+ g2 as getSmallPanelVariant,
27
45
  i as initSharedFeatures,
28
46
  q as isEligibleForCampaign,
29
47
  e as isInitialized,
@@ -32,6 +50,8 @@ export {
32
50
  p as trackClose,
33
51
  t as trackImpression,
34
52
  a2 as useCampaign,
35
- u2 as useCampaigns
53
+ u2 as useCampaigns,
54
+ b2 as useOneTimeAdModal,
55
+ c2 as useUpdateAdModal
36
56
  };
37
57
  //# sourceMappingURL=index.js.map
@@ -295,44 +295,32 @@ export interface CampaignAnalytics {
295
295
  }>;
296
296
  }
297
297
  /**
298
- * Props for small panel variants
298
+ * Props for small panel variant components
299
299
  */
300
300
  export interface SmallPanelProps {
301
- campaign: Campaign;
302
- product: Product;
303
- variant: SmallPanelVariant;
304
- onClose: () => void;
305
- onClick: () => void;
301
+ /** Campaign with product data */
302
+ campaign: CampaignWithProduct;
303
+ /** Called when user clicks CTA */
304
+ onCTAClick?: () => void;
305
+ /** Called when user closes/dismisses the ad */
306
+ onClose?: () => void;
306
307
  }
307
308
  /**
308
- * Props for large panel variants
309
+ * Props for large panel variant components
309
310
  */
310
311
  export interface LargePanelProps {
311
- campaign: Campaign;
312
- product: Product;
313
- variant: LargePanelVariant;
314
- onClose: () => void;
315
- onClick: () => void;
316
- }
317
- /**
318
- * Props for ad slider component
319
- */
320
- export interface AdSliderProps {
321
- placement: AdPlacement;
322
- variant?: SmallPanelVariant;
323
- autoplay?: boolean;
324
- interval?: number;
325
- maxCampaigns?: number;
326
- className?: string;
327
- }
328
- /**
329
- * Props for ad modal component
330
- */
331
- export interface AdModalProps {
332
- open: boolean;
333
- onOpenChange: (open: boolean) => void;
334
- campaign: CampaignWithProduct | null;
335
- variant?: LargePanelVariant;
312
+ /** Campaign with product data */
313
+ campaign: CampaignWithProduct;
314
+ /** Called when user clicks CTA */
315
+ onCTAClick?: () => void;
316
+ /** Called when user closes/dismisses the ad */
317
+ onClose?: () => void;
318
+ /** Whether to show slide indicator */
319
+ showIndicator?: boolean;
320
+ /** Current slide index (for carousel) */
321
+ currentIndex?: number;
322
+ /** Total number of slides (for carousel) */
323
+ totalCount?: number;
336
324
  }
337
325
  /**
338
326
  * Props for ad panel component
@@ -1 +1 @@
1
- {"version":3,"file":"campaigns.d.ts","sourceRoot":"","sources":["../../src/types/campaigns.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"campaigns.d.ts","sourceRoot":"","sources":["../../src/types/campaigns.ts"],"names":[],"mappings":"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"}
@@ -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 variants\n */\nexport interface SmallPanelProps {\n campaign: Campaign;\n product: Product;\n variant: SmallPanelVariant;\n onClose: () => void;\n onClick: () => void;\n}\n\n/**\n * Props for large panel variants\n */\nexport interface LargePanelProps {\n campaign: Campaign;\n product: Product;\n variant: LargePanelVariant;\n onClose: () => void;\n onClick: () => void;\n}\n\n/**\n * Props for ad slider component\n */\nexport interface AdSliderProps {\n placement: AdPlacement;\n variant?: SmallPanelVariant;\n autoplay?: boolean;\n interval?: number;\n maxCampaigns?: number;\n className?: string;\n}\n\n/**\n * Props for ad modal component\n */\nexport interface AdModalProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n campaign: CampaignWithProduct | null;\n variant?: LargePanelVariant;\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":";;AAybO,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"],"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 +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 variants\n */\nexport interface SmallPanelProps {\n campaign: Campaign;\n product: Product;\n variant: SmallPanelVariant;\n onClose: () => void;\n onClick: () => void;\n}\n\n/**\n * Props for large panel variants\n */\nexport interface LargePanelProps {\n campaign: Campaign;\n product: Product;\n variant: LargePanelVariant;\n onClose: () => void;\n onClick: () => void;\n}\n\n/**\n * Props for ad slider component\n */\nexport interface AdSliderProps {\n placement: AdPlacement;\n variant?: SmallPanelVariant;\n autoplay?: boolean;\n interval?: number;\n maxCampaigns?: number;\n className?: string;\n}\n\n/**\n * Props for ad modal component\n */\nexport interface AdModalProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n campaign: CampaignWithProduct | null;\n variant?: LargePanelVariant;\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":"AAybO,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"],"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;"}
@@ -92,6 +92,61 @@ function useCampaigns(options) {
92
92
  function useCampaign(options) {
93
93
  return useCampaigns({ ...options, maxCampaigns: 1 });
94
94
  }
95
+ const STORAGE_KEYS = {
96
+ oneTimeShown: "shared_features_onetime_ad_shown",
97
+ appVersion: "shared_features_app_version"
98
+ };
99
+ function useOneTimeAdModal() {
100
+ const [hasShown, setHasShown] = react.useState(false);
101
+ const [shouldShow, setShouldShow] = react.useState(false);
102
+ react.useEffect(() => {
103
+ const hasSeenModal = localStorage.getItem(STORAGE_KEYS.oneTimeShown);
104
+ if (!hasSeenModal) {
105
+ setShouldShow(true);
106
+ }
107
+ }, []);
108
+ const markAsShown = react.useCallback(() => {
109
+ localStorage.setItem(STORAGE_KEYS.oneTimeShown, "true");
110
+ setHasShown(true);
111
+ setShouldShow(false);
112
+ }, []);
113
+ return {
114
+ /** Whether the modal should be displayed */
115
+ shouldShow: shouldShow && !hasShown,
116
+ /** Mark the modal as shown (call when user dismisses) */
117
+ markAsShown
118
+ };
119
+ }
120
+ function useUpdateAdModal(currentVersion) {
121
+ const version = currentVersion || void 0 || "1.0.0";
122
+ const [shouldShow, setShouldShow] = react.useState(false);
123
+ const [previousVersion, setPreviousVersion] = react.useState(null);
124
+ react.useEffect(() => {
125
+ const storedVersion = localStorage.getItem(STORAGE_KEYS.appVersion);
126
+ if (!storedVersion) {
127
+ localStorage.setItem(STORAGE_KEYS.appVersion, version);
128
+ } else if (storedVersion !== version) {
129
+ setShouldShow(true);
130
+ setPreviousVersion(storedVersion);
131
+ }
132
+ }, [version]);
133
+ const markAsShown = react.useCallback(() => {
134
+ localStorage.setItem(STORAGE_KEYS.appVersion, version);
135
+ setShouldShow(false);
136
+ }, [version]);
137
+ return {
138
+ /** Whether the modal should be displayed */
139
+ shouldShow,
140
+ /** Previous app version (before update) */
141
+ previousVersion,
142
+ /** Current app version */
143
+ currentVersion: version,
144
+ /** Mark the modal as shown (call when user dismisses) */
145
+ markAsShown
146
+ };
147
+ }
95
148
  exports.useCampaign = useCampaign;
96
149
  exports.useCampaigns = useCampaigns;
97
- //# sourceMappingURL=useCampaigns-BNOHpETm.cjs.map
150
+ exports.useOneTimeAdModal = useOneTimeAdModal;
151
+ exports.useUpdateAdModal = useUpdateAdModal;
152
+ //# sourceMappingURL=useCampaigns-BKGqKAUo.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCampaigns-BKGqKAUo.cjs","sources":["../src/hooks/useCampaigns.ts"],"sourcesContent":["/**\n * useCampaigns Hook\n *\n * React hook for fetching and displaying campaigns in consumer projects.\n *\n * @author Ahsan Mahmood <aoneahsan@gmail.com>\n */\n\nimport { useState, useEffect, useCallback } from 'react';\nimport { fetchActiveCampaigns, clearCampaignsCache } from '../services/campaigns';\nimport {\n trackImpression,\n trackClick,\n trackClose,\n isEligibleForCampaign,\n} from '../services/analytics';\nimport { isInitialized } from '../firebase/config';\nimport type {\n CampaignWithProduct,\n AdPlacement,\n SmallPanelVariant,\n LargePanelVariant,\n} from '../types/campaigns';\n\nexport interface UseCampaignsOptions {\n /** Placement to fetch campaigns for */\n placement: AdPlacement;\n /** Maximum number of campaigns to fetch */\n maxCampaigns?: number;\n /** Whether to auto-fetch on mount (default: true) */\n autoFetch?: boolean;\n /** Default variant for small placements */\n defaultSmallVariant?: SmallPanelVariant;\n /** Default variant for large placements */\n defaultLargeVariant?: LargePanelVariant;\n}\n\nexport interface UseCampaignsResult {\n /** List of eligible campaigns with product data */\n campaigns: CampaignWithProduct[];\n /** Single campaign (first eligible) - convenience accessor */\n campaign: CampaignWithProduct | null;\n /** Whether campaigns are being fetched */\n loading: boolean;\n /** Error message if fetch failed */\n error: string | null;\n /** Refetch campaigns */\n refetch: () => Promise<void>;\n /** Record impression for a campaign */\n recordImpression: (campaign: CampaignWithProduct) => Promise<void>;\n /** Record click for a campaign */\n recordClick: (campaign: CampaignWithProduct) => Promise<void>;\n /** Record close/dismiss for a campaign */\n recordClose: (campaign: CampaignWithProduct) => Promise<void>;\n}\n\n/**\n * Hook to fetch and manage campaigns for a specific placement\n *\n * @example\n * ```tsx\n * const { campaigns, loading, recordImpression, recordClick } = useCampaigns({\n * placement: 'footer_slider',\n * maxCampaigns: 5,\n * });\n *\n * if (loading) return <Spinner />;\n *\n * return (\n * <AdSlider\n * campaigns={campaigns}\n * onImpression={recordImpression}\n * onClick={recordClick}\n * />\n * );\n * ```\n */\nexport function useCampaigns(options: UseCampaignsOptions): UseCampaignsResult {\n const {\n placement,\n maxCampaigns = 5,\n autoFetch = true,\n defaultSmallVariant = 'small_panel_2',\n defaultLargeVariant: _defaultLargeVariant = 'large_slider_1',\n } = options;\n // Note: _defaultLargeVariant reserved for large variant components\n\n const [campaigns, setCampaigns] = useState<CampaignWithProduct[]>([]);\n const [loading, setLoading] = useState(autoFetch);\n const [error, setError] = useState<string | null>(null);\n\n const fetchCampaigns = useCallback(async () => {\n if (!isInitialized()) {\n setError('shared-features not initialized');\n setLoading(false);\n return;\n }\n\n setLoading(true);\n setError(null);\n\n try {\n const allCampaigns = await fetchActiveCampaigns(placement);\n\n // Filter by frequency capping\n const eligibleCampaigns: CampaignWithProduct[] = [];\n\n for (const campaign of allCampaigns) {\n const eligible = await isEligibleForCampaign(\n campaign.id,\n campaign.frequencyDays\n );\n if (eligible) {\n eligibleCampaigns.push(campaign);\n if (eligibleCampaigns.length >= maxCampaigns) break;\n }\n }\n\n setCampaigns(eligibleCampaigns);\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Failed to fetch campaigns';\n setError(message);\n console.error('[shared-features] Error fetching campaigns:', err);\n } finally {\n setLoading(false);\n }\n }, [placement, maxCampaigns]);\n\n // Auto-fetch on mount\n useEffect(() => {\n if (autoFetch) {\n fetchCampaigns();\n }\n }, [autoFetch, fetchCampaigns]);\n\n // Record impression\n const handleRecordImpression = useCallback(\n async (campaign: CampaignWithProduct) => {\n const variant = campaign.variant.startsWith('small_')\n ? campaign.variant\n : campaign.variant.startsWith('large_')\n ? campaign.variant\n : defaultSmallVariant;\n\n await trackImpression(\n campaign.id,\n campaign.productId,\n placement,\n variant,\n campaign.frequencyDays\n );\n },\n [placement, defaultSmallVariant]\n );\n\n // Record click\n const handleRecordClick = useCallback(\n async (campaign: CampaignWithProduct) => {\n const variant = campaign.variant;\n await trackClick(campaign.id, campaign.productId, placement, variant);\n },\n [placement]\n );\n\n // Record close\n const handleRecordClose = useCallback(\n async (campaign: CampaignWithProduct) => {\n const variant = campaign.variant;\n await trackClose(campaign.id, campaign.productId, placement, variant);\n },\n [placement]\n );\n\n // Refetch with cache clear\n const refetch = useCallback(async () => {\n clearCampaignsCache();\n await fetchCampaigns();\n }, [fetchCampaigns]);\n\n return {\n campaigns,\n campaign: campaigns[0] || null,\n loading,\n error,\n refetch,\n recordImpression: handleRecordImpression,\n recordClick: handleRecordClick,\n recordClose: handleRecordClose,\n };\n}\n\n/**\n * Hook to fetch a single campaign for a placement\n * Convenience wrapper around useCampaigns\n */\nexport function useCampaign(options: Omit<UseCampaignsOptions, 'maxCampaigns'>) {\n return useCampaigns({ ...options, maxCampaigns: 1 });\n}\n\n// Storage keys for modal hooks\nconst STORAGE_KEYS = {\n oneTimeShown: 'shared_features_onetime_ad_shown',\n appVersion: 'shared_features_app_version',\n} as const;\n\n/**\n * Hook to manage one-time ad modal visibility\n * Shows modal on first visit, then remembers user has seen it\n *\n * @example\n * ```tsx\n * const { shouldShow, markAsShown } = useOneTimeAdModal();\n *\n * if (shouldShow) {\n * return <AdModal onClose={markAsShown} />;\n * }\n * ```\n */\nexport function useOneTimeAdModal() {\n const [hasShown, setHasShown] = useState(false);\n const [shouldShow, setShouldShow] = useState(false);\n\n useEffect(() => {\n // Check if modal has been shown before\n const hasSeenModal = localStorage.getItem(STORAGE_KEYS.oneTimeShown);\n if (!hasSeenModal) {\n setShouldShow(true);\n }\n }, []);\n\n const markAsShown = useCallback(() => {\n localStorage.setItem(STORAGE_KEYS.oneTimeShown, 'true');\n setHasShown(true);\n setShouldShow(false);\n }, []);\n\n return {\n /** Whether the modal should be displayed */\n shouldShow: shouldShow && !hasShown,\n /** Mark the modal as shown (call when user dismisses) */\n markAsShown,\n };\n}\n\n/**\n * Hook to manage update ad modal visibility\n * Shows modal when app version changes\n *\n * @param currentVersion - Current app version (defaults to VITE_APP_VERSION env var or '1.0.0')\n *\n * @example\n * ```tsx\n * const { shouldShow, currentVersion, markAsShown } = useUpdateAdModal();\n *\n * if (shouldShow) {\n * return <AdUpdateModal version={currentVersion} onClose={markAsShown} />;\n * }\n * ```\n */\nexport function useUpdateAdModal(currentVersion?: string) {\n const version = currentVersion || import.meta.env.VITE_APP_VERSION || '1.0.0';\n const [shouldShow, setShouldShow] = useState(false);\n const [previousVersion, setPreviousVersion] = useState<string | null>(null);\n\n useEffect(() => {\n const storedVersion = localStorage.getItem(STORAGE_KEYS.appVersion);\n\n if (!storedVersion) {\n // First time user - store version but don't show update modal\n localStorage.setItem(STORAGE_KEYS.appVersion, version);\n } else if (storedVersion !== version) {\n // Version changed - show update modal\n setShouldShow(true);\n setPreviousVersion(storedVersion);\n }\n }, [version]);\n\n const markAsShown = useCallback(() => {\n localStorage.setItem(STORAGE_KEYS.appVersion, version);\n setShouldShow(false);\n }, [version]);\n\n return {\n /** Whether the modal should be displayed */\n shouldShow,\n /** Previous app version (before update) */\n previousVersion,\n /** Current app version */\n currentVersion: version,\n /** Mark the modal as shown (call when user dismisses) */\n markAsShown,\n };\n}\n"],"names":["useState","useCallback","isInitialized","fetchActiveCampaigns","isEligibleForCampaign","useEffect","trackImpression","trackClick","trackClose","clearCampaignsCache"],"mappings":"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"}
@@ -91,8 +91,63 @@ function useCampaigns(options) {
91
91
  function useCampaign(options) {
92
92
  return useCampaigns({ ...options, maxCampaigns: 1 });
93
93
  }
94
+ const STORAGE_KEYS = {
95
+ oneTimeShown: "shared_features_onetime_ad_shown",
96
+ appVersion: "shared_features_app_version"
97
+ };
98
+ function useOneTimeAdModal() {
99
+ const [hasShown, setHasShown] = useState(false);
100
+ const [shouldShow, setShouldShow] = useState(false);
101
+ useEffect(() => {
102
+ const hasSeenModal = localStorage.getItem(STORAGE_KEYS.oneTimeShown);
103
+ if (!hasSeenModal) {
104
+ setShouldShow(true);
105
+ }
106
+ }, []);
107
+ const markAsShown = useCallback(() => {
108
+ localStorage.setItem(STORAGE_KEYS.oneTimeShown, "true");
109
+ setHasShown(true);
110
+ setShouldShow(false);
111
+ }, []);
112
+ return {
113
+ /** Whether the modal should be displayed */
114
+ shouldShow: shouldShow && !hasShown,
115
+ /** Mark the modal as shown (call when user dismisses) */
116
+ markAsShown
117
+ };
118
+ }
119
+ function useUpdateAdModal(currentVersion) {
120
+ const version = currentVersion || void 0 || "1.0.0";
121
+ const [shouldShow, setShouldShow] = useState(false);
122
+ const [previousVersion, setPreviousVersion] = useState(null);
123
+ useEffect(() => {
124
+ const storedVersion = localStorage.getItem(STORAGE_KEYS.appVersion);
125
+ if (!storedVersion) {
126
+ localStorage.setItem(STORAGE_KEYS.appVersion, version);
127
+ } else if (storedVersion !== version) {
128
+ setShouldShow(true);
129
+ setPreviousVersion(storedVersion);
130
+ }
131
+ }, [version]);
132
+ const markAsShown = useCallback(() => {
133
+ localStorage.setItem(STORAGE_KEYS.appVersion, version);
134
+ setShouldShow(false);
135
+ }, [version]);
136
+ return {
137
+ /** Whether the modal should be displayed */
138
+ shouldShow,
139
+ /** Previous app version (before update) */
140
+ previousVersion,
141
+ /** Current app version */
142
+ currentVersion: version,
143
+ /** Mark the modal as shown (call when user dismisses) */
144
+ markAsShown
145
+ };
146
+ }
94
147
  export {
95
148
  useCampaign as a,
149
+ useOneTimeAdModal as b,
150
+ useUpdateAdModal as c,
96
151
  useCampaigns as u
97
152
  };
98
- //# sourceMappingURL=useCampaigns-3NxODLLs.js.map
153
+ //# sourceMappingURL=useCampaigns-osYDc6WC.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useCampaigns-3NxODLLs.js","sources":["../src/hooks/useCampaigns.ts"],"sourcesContent":["/**\n * useCampaigns Hook\n *\n * React hook for fetching and displaying campaigns in consumer projects.\n *\n * @author Ahsan Mahmood <aoneahsan@gmail.com>\n */\n\nimport { useState, useEffect, useCallback } from 'react';\nimport { fetchActiveCampaigns, clearCampaignsCache } from '../services/campaigns';\nimport {\n trackImpression,\n trackClick,\n trackClose,\n isEligibleForCampaign,\n} from '../services/analytics';\nimport { isInitialized } from '../firebase/config';\nimport type {\n CampaignWithProduct,\n AdPlacement,\n SmallPanelVariant,\n LargePanelVariant,\n} from '../types/campaigns';\n\nexport interface UseCampaignsOptions {\n /** Placement to fetch campaigns for */\n placement: AdPlacement;\n /** Maximum number of campaigns to fetch */\n maxCampaigns?: number;\n /** Whether to auto-fetch on mount (default: true) */\n autoFetch?: boolean;\n /** Default variant for small placements */\n defaultSmallVariant?: SmallPanelVariant;\n /** Default variant for large placements */\n defaultLargeVariant?: LargePanelVariant;\n}\n\nexport interface UseCampaignsResult {\n /** List of eligible campaigns with product data */\n campaigns: CampaignWithProduct[];\n /** Single campaign (first eligible) - convenience accessor */\n campaign: CampaignWithProduct | null;\n /** Whether campaigns are being fetched */\n loading: boolean;\n /** Error message if fetch failed */\n error: string | null;\n /** Refetch campaigns */\n refetch: () => Promise<void>;\n /** Record impression for a campaign */\n recordImpression: (campaign: CampaignWithProduct) => Promise<void>;\n /** Record click for a campaign */\n recordClick: (campaign: CampaignWithProduct) => Promise<void>;\n /** Record close/dismiss for a campaign */\n recordClose: (campaign: CampaignWithProduct) => Promise<void>;\n}\n\n/**\n * Hook to fetch and manage campaigns for a specific placement\n *\n * @example\n * ```tsx\n * const { campaigns, loading, recordImpression, recordClick } = useCampaigns({\n * placement: 'footer_slider',\n * maxCampaigns: 5,\n * });\n *\n * if (loading) return <Spinner />;\n *\n * return (\n * <AdSlider\n * campaigns={campaigns}\n * onImpression={recordImpression}\n * onClick={recordClick}\n * />\n * );\n * ```\n */\nexport function useCampaigns(options: UseCampaignsOptions): UseCampaignsResult {\n const {\n placement,\n maxCampaigns = 5,\n autoFetch = true,\n defaultSmallVariant = 'small_panel_2',\n defaultLargeVariant: _defaultLargeVariant = 'large_slider_1',\n } = options;\n // Note: _defaultLargeVariant reserved for large variant components\n\n const [campaigns, setCampaigns] = useState<CampaignWithProduct[]>([]);\n const [loading, setLoading] = useState(autoFetch);\n const [error, setError] = useState<string | null>(null);\n\n const fetchCampaigns = useCallback(async () => {\n if (!isInitialized()) {\n setError('shared-features not initialized');\n setLoading(false);\n return;\n }\n\n setLoading(true);\n setError(null);\n\n try {\n const allCampaigns = await fetchActiveCampaigns(placement);\n\n // Filter by frequency capping\n const eligibleCampaigns: CampaignWithProduct[] = [];\n\n for (const campaign of allCampaigns) {\n const eligible = await isEligibleForCampaign(\n campaign.id,\n campaign.frequencyDays\n );\n if (eligible) {\n eligibleCampaigns.push(campaign);\n if (eligibleCampaigns.length >= maxCampaigns) break;\n }\n }\n\n setCampaigns(eligibleCampaigns);\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Failed to fetch campaigns';\n setError(message);\n console.error('[shared-features] Error fetching campaigns:', err);\n } finally {\n setLoading(false);\n }\n }, [placement, maxCampaigns]);\n\n // Auto-fetch on mount\n useEffect(() => {\n if (autoFetch) {\n fetchCampaigns();\n }\n }, [autoFetch, fetchCampaigns]);\n\n // Record impression\n const handleRecordImpression = useCallback(\n async (campaign: CampaignWithProduct) => {\n const variant = campaign.variant.startsWith('small_')\n ? campaign.variant\n : campaign.variant.startsWith('large_')\n ? campaign.variant\n : defaultSmallVariant;\n\n await trackImpression(\n campaign.id,\n campaign.productId,\n placement,\n variant,\n campaign.frequencyDays\n );\n },\n [placement, defaultSmallVariant]\n );\n\n // Record click\n const handleRecordClick = useCallback(\n async (campaign: CampaignWithProduct) => {\n const variant = campaign.variant;\n await trackClick(campaign.id, campaign.productId, placement, variant);\n },\n [placement]\n );\n\n // Record close\n const handleRecordClose = useCallback(\n async (campaign: CampaignWithProduct) => {\n const variant = campaign.variant;\n await trackClose(campaign.id, campaign.productId, placement, variant);\n },\n [placement]\n );\n\n // Refetch with cache clear\n const refetch = useCallback(async () => {\n clearCampaignsCache();\n await fetchCampaigns();\n }, [fetchCampaigns]);\n\n return {\n campaigns,\n campaign: campaigns[0] || null,\n loading,\n error,\n refetch,\n recordImpression: handleRecordImpression,\n recordClick: handleRecordClick,\n recordClose: handleRecordClose,\n };\n}\n\n/**\n * Hook to fetch a single campaign for a placement\n * Convenience wrapper around useCampaigns\n */\nexport function useCampaign(options: Omit<UseCampaignsOptions, 'maxCampaigns'>) {\n return useCampaigns({ ...options, maxCampaigns: 1 });\n}\n"],"names":[],"mappings":";;AA6EO,SAAS,aAAa,SAAkD;AAC7E,QAAM;AAAA,IACJ;AAAA,IACA,eAAe;AAAA,IACf,YAAY;AAAA,IACZ,sBAAsB;AAAA,IACtB,qBAAqB,uBAAuB;AAAA,EAAA,IAC1C;AAGJ,QAAM,CAAC,WAAW,YAAY,IAAI,SAAgC,CAAA,CAAE;AACpE,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,SAAS;AAChD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAwB,IAAI;AAEtD,QAAM,iBAAiB,YAAY,YAAY;AAC7C,QAAI,CAAC,iBAAiB;AACpB,eAAS,iCAAiC;AAC1C,iBAAW,KAAK;AAChB;AAAA,IACF;AAEA,eAAW,IAAI;AACf,aAAS,IAAI;AAEb,QAAI;AACF,YAAM,eAAe,MAAM,qBAAqB,SAAS;AAGzD,YAAM,oBAA2C,CAAA;AAEjD,iBAAW,YAAY,cAAc;AACnC,cAAM,WAAW,MAAM;AAAA,UACrB,SAAS;AAAA,UACT,SAAS;AAAA,QAAA;AAEX,YAAI,UAAU;AACZ,4BAAkB,KAAK,QAAQ;AAC/B,cAAI,kBAAkB,UAAU,aAAc;AAAA,QAChD;AAAA,MACF;AAEA,mBAAa,iBAAiB;AAAA,IAChC,SAAS,KAAK;AACZ,YAAM,UAAU,eAAe,QAAQ,IAAI,UAAU;AACrD,eAAS,OAAO;AAChB,cAAQ,MAAM,+CAA+C,GAAG;AAAA,IAClE,UAAA;AACE,iBAAW,KAAK;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,WAAW,YAAY,CAAC;AAG5B,YAAU,MAAM;AACd,QAAI,WAAW;AACb,qBAAA;AAAA,IACF;AAAA,EACF,GAAG,CAAC,WAAW,cAAc,CAAC;AAG9B,QAAM,yBAAyB;AAAA,IAC7B,OAAO,aAAkC;AACvC,YAAM,UAAU,SAAS,QAAQ,WAAW,QAAQ,IAChD,SAAS,UACT,SAAS,QAAQ,WAAW,QAAQ,IAClC,SAAS,UACT;AAEN,YAAM;AAAA,QACJ,SAAS;AAAA,QACT,SAAS;AAAA,QACT;AAAA,QACA;AAAA,QACA,SAAS;AAAA,MAAA;AAAA,IAEb;AAAA,IACA,CAAC,WAAW,mBAAmB;AAAA,EAAA;AAIjC,QAAM,oBAAoB;AAAA,IACxB,OAAO,aAAkC;AACvC,YAAM,UAAU,SAAS;AACzB,YAAM,WAAW,SAAS,IAAI,SAAS,WAAW,WAAW,OAAO;AAAA,IACtE;AAAA,IACA,CAAC,SAAS;AAAA,EAAA;AAIZ,QAAM,oBAAoB;AAAA,IACxB,OAAO,aAAkC;AACvC,YAAM,UAAU,SAAS;AACzB,YAAM,WAAW,SAAS,IAAI,SAAS,WAAW,WAAW,OAAO;AAAA,IACtE;AAAA,IACA,CAAC,SAAS;AAAA,EAAA;AAIZ,QAAM,UAAU,YAAY,YAAY;AACtC,wBAAA;AACA,UAAM,eAAA;AAAA,EACR,GAAG,CAAC,cAAc,CAAC;AAEnB,SAAO;AAAA,IACL;AAAA,IACA,UAAU,UAAU,CAAC,KAAK;AAAA,IAC1B;AAAA,IACA;AAAA,IACA;AAAA,IACA,kBAAkB;AAAA,IAClB,aAAa;AAAA,IACb,aAAa;AAAA,EAAA;AAEjB;AAMO,SAAS,YAAY,SAAoD;AAC9E,SAAO,aAAa,EAAE,GAAG,SAAS,cAAc,GAAG;AACrD;"}
1
+ {"version":3,"file":"useCampaigns-osYDc6WC.js","sources":["../src/hooks/useCampaigns.ts"],"sourcesContent":["/**\n * useCampaigns Hook\n *\n * React hook for fetching and displaying campaigns in consumer projects.\n *\n * @author Ahsan Mahmood <aoneahsan@gmail.com>\n */\n\nimport { useState, useEffect, useCallback } from 'react';\nimport { fetchActiveCampaigns, clearCampaignsCache } from '../services/campaigns';\nimport {\n trackImpression,\n trackClick,\n trackClose,\n isEligibleForCampaign,\n} from '../services/analytics';\nimport { isInitialized } from '../firebase/config';\nimport type {\n CampaignWithProduct,\n AdPlacement,\n SmallPanelVariant,\n LargePanelVariant,\n} from '../types/campaigns';\n\nexport interface UseCampaignsOptions {\n /** Placement to fetch campaigns for */\n placement: AdPlacement;\n /** Maximum number of campaigns to fetch */\n maxCampaigns?: number;\n /** Whether to auto-fetch on mount (default: true) */\n autoFetch?: boolean;\n /** Default variant for small placements */\n defaultSmallVariant?: SmallPanelVariant;\n /** Default variant for large placements */\n defaultLargeVariant?: LargePanelVariant;\n}\n\nexport interface UseCampaignsResult {\n /** List of eligible campaigns with product data */\n campaigns: CampaignWithProduct[];\n /** Single campaign (first eligible) - convenience accessor */\n campaign: CampaignWithProduct | null;\n /** Whether campaigns are being fetched */\n loading: boolean;\n /** Error message if fetch failed */\n error: string | null;\n /** Refetch campaigns */\n refetch: () => Promise<void>;\n /** Record impression for a campaign */\n recordImpression: (campaign: CampaignWithProduct) => Promise<void>;\n /** Record click for a campaign */\n recordClick: (campaign: CampaignWithProduct) => Promise<void>;\n /** Record close/dismiss for a campaign */\n recordClose: (campaign: CampaignWithProduct) => Promise<void>;\n}\n\n/**\n * Hook to fetch and manage campaigns for a specific placement\n *\n * @example\n * ```tsx\n * const { campaigns, loading, recordImpression, recordClick } = useCampaigns({\n * placement: 'footer_slider',\n * maxCampaigns: 5,\n * });\n *\n * if (loading) return <Spinner />;\n *\n * return (\n * <AdSlider\n * campaigns={campaigns}\n * onImpression={recordImpression}\n * onClick={recordClick}\n * />\n * );\n * ```\n */\nexport function useCampaigns(options: UseCampaignsOptions): UseCampaignsResult {\n const {\n placement,\n maxCampaigns = 5,\n autoFetch = true,\n defaultSmallVariant = 'small_panel_2',\n defaultLargeVariant: _defaultLargeVariant = 'large_slider_1',\n } = options;\n // Note: _defaultLargeVariant reserved for large variant components\n\n const [campaigns, setCampaigns] = useState<CampaignWithProduct[]>([]);\n const [loading, setLoading] = useState(autoFetch);\n const [error, setError] = useState<string | null>(null);\n\n const fetchCampaigns = useCallback(async () => {\n if (!isInitialized()) {\n setError('shared-features not initialized');\n setLoading(false);\n return;\n }\n\n setLoading(true);\n setError(null);\n\n try {\n const allCampaigns = await fetchActiveCampaigns(placement);\n\n // Filter by frequency capping\n const eligibleCampaigns: CampaignWithProduct[] = [];\n\n for (const campaign of allCampaigns) {\n const eligible = await isEligibleForCampaign(\n campaign.id,\n campaign.frequencyDays\n );\n if (eligible) {\n eligibleCampaigns.push(campaign);\n if (eligibleCampaigns.length >= maxCampaigns) break;\n }\n }\n\n setCampaigns(eligibleCampaigns);\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Failed to fetch campaigns';\n setError(message);\n console.error('[shared-features] Error fetching campaigns:', err);\n } finally {\n setLoading(false);\n }\n }, [placement, maxCampaigns]);\n\n // Auto-fetch on mount\n useEffect(() => {\n if (autoFetch) {\n fetchCampaigns();\n }\n }, [autoFetch, fetchCampaigns]);\n\n // Record impression\n const handleRecordImpression = useCallback(\n async (campaign: CampaignWithProduct) => {\n const variant = campaign.variant.startsWith('small_')\n ? campaign.variant\n : campaign.variant.startsWith('large_')\n ? campaign.variant\n : defaultSmallVariant;\n\n await trackImpression(\n campaign.id,\n campaign.productId,\n placement,\n variant,\n campaign.frequencyDays\n );\n },\n [placement, defaultSmallVariant]\n );\n\n // Record click\n const handleRecordClick = useCallback(\n async (campaign: CampaignWithProduct) => {\n const variant = campaign.variant;\n await trackClick(campaign.id, campaign.productId, placement, variant);\n },\n [placement]\n );\n\n // Record close\n const handleRecordClose = useCallback(\n async (campaign: CampaignWithProduct) => {\n const variant = campaign.variant;\n await trackClose(campaign.id, campaign.productId, placement, variant);\n },\n [placement]\n );\n\n // Refetch with cache clear\n const refetch = useCallback(async () => {\n clearCampaignsCache();\n await fetchCampaigns();\n }, [fetchCampaigns]);\n\n return {\n campaigns,\n campaign: campaigns[0] || null,\n loading,\n error,\n refetch,\n recordImpression: handleRecordImpression,\n recordClick: handleRecordClick,\n recordClose: handleRecordClose,\n };\n}\n\n/**\n * Hook to fetch a single campaign for a placement\n * Convenience wrapper around useCampaigns\n */\nexport function useCampaign(options: Omit<UseCampaignsOptions, 'maxCampaigns'>) {\n return useCampaigns({ ...options, maxCampaigns: 1 });\n}\n\n// Storage keys for modal hooks\nconst STORAGE_KEYS = {\n oneTimeShown: 'shared_features_onetime_ad_shown',\n appVersion: 'shared_features_app_version',\n} as const;\n\n/**\n * Hook to manage one-time ad modal visibility\n * Shows modal on first visit, then remembers user has seen it\n *\n * @example\n * ```tsx\n * const { shouldShow, markAsShown } = useOneTimeAdModal();\n *\n * if (shouldShow) {\n * return <AdModal onClose={markAsShown} />;\n * }\n * ```\n */\nexport function useOneTimeAdModal() {\n const [hasShown, setHasShown] = useState(false);\n const [shouldShow, setShouldShow] = useState(false);\n\n useEffect(() => {\n // Check if modal has been shown before\n const hasSeenModal = localStorage.getItem(STORAGE_KEYS.oneTimeShown);\n if (!hasSeenModal) {\n setShouldShow(true);\n }\n }, []);\n\n const markAsShown = useCallback(() => {\n localStorage.setItem(STORAGE_KEYS.oneTimeShown, 'true');\n setHasShown(true);\n setShouldShow(false);\n }, []);\n\n return {\n /** Whether the modal should be displayed */\n shouldShow: shouldShow && !hasShown,\n /** Mark the modal as shown (call when user dismisses) */\n markAsShown,\n };\n}\n\n/**\n * Hook to manage update ad modal visibility\n * Shows modal when app version changes\n *\n * @param currentVersion - Current app version (defaults to VITE_APP_VERSION env var or '1.0.0')\n *\n * @example\n * ```tsx\n * const { shouldShow, currentVersion, markAsShown } = useUpdateAdModal();\n *\n * if (shouldShow) {\n * return <AdUpdateModal version={currentVersion} onClose={markAsShown} />;\n * }\n * ```\n */\nexport function useUpdateAdModal(currentVersion?: string) {\n const version = currentVersion || import.meta.env.VITE_APP_VERSION || '1.0.0';\n const [shouldShow, setShouldShow] = useState(false);\n const [previousVersion, setPreviousVersion] = useState<string | null>(null);\n\n useEffect(() => {\n const storedVersion = localStorage.getItem(STORAGE_KEYS.appVersion);\n\n if (!storedVersion) {\n // First time user - store version but don't show update modal\n localStorage.setItem(STORAGE_KEYS.appVersion, version);\n } else if (storedVersion !== version) {\n // Version changed - show update modal\n setShouldShow(true);\n setPreviousVersion(storedVersion);\n }\n }, [version]);\n\n const markAsShown = useCallback(() => {\n localStorage.setItem(STORAGE_KEYS.appVersion, version);\n setShouldShow(false);\n }, [version]);\n\n return {\n /** Whether the modal should be displayed */\n shouldShow,\n /** Previous app version (before update) */\n previousVersion,\n /** Current app version */\n currentVersion: version,\n /** Mark the modal as shown (call when user dismisses) */\n markAsShown,\n };\n}\n"],"names":[],"mappings":"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"}