shared-features 0.0.8 → 0.1.0

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 (91) hide show
  1. package/README.md +205 -2
  2. package/dist/{admin-notifications-D9n9h-eY.cjs → admin-notifications-D1GgYCJW.cjs} +20 -20
  3. package/dist/{admin-notifications-D9n9h-eY.cjs.map → admin-notifications-D1GgYCJW.cjs.map} +1 -1
  4. package/dist/{admin-notifications-p1dy3zIP.js → admin-notifications-NI7I76uY.js} +13 -13
  5. package/dist/{admin-notifications-p1dy3zIP.js.map → admin-notifications-NI7I76uY.js.map} +1 -1
  6. package/dist/{broadcasts-3_WfQMNL.cjs → broadcasts-BMoTZIuX.cjs} +10 -10
  7. package/dist/{broadcasts-3_WfQMNL.cjs.map → broadcasts-BMoTZIuX.cjs.map} +1 -1
  8. package/dist/{broadcasts-DgZUzqMf.js → broadcasts-DnzZkCoy.js} +12 -12
  9. package/dist/{broadcasts-DgZUzqMf.js.map → broadcasts-DnzZkCoy.js.map} +1 -1
  10. package/dist/commonFeatures-Bdt0UZox.js +1255 -0
  11. package/dist/commonFeatures-Bdt0UZox.js.map +1 -0
  12. package/dist/commonFeatures-CiqxxOin.cjs +1276 -0
  13. package/dist/commonFeatures-CiqxxOin.cjs.map +1 -0
  14. package/dist/commonFeatures-Cr5g1E4M.cjs +200 -0
  15. package/dist/commonFeatures-Cr5g1E4M.cjs.map +1 -0
  16. package/dist/commonFeatures-HT-UO7HW.js +201 -0
  17. package/dist/commonFeatures-HT-UO7HW.js.map +1 -0
  18. package/dist/components/common/index.d.ts +53 -0
  19. package/dist/components/common/index.d.ts.map +1 -0
  20. package/dist/components/index.cjs +31 -23
  21. package/dist/components/index.cjs.map +1 -1
  22. package/dist/components/index.d.ts +1 -0
  23. package/dist/components/index.d.ts.map +1 -1
  24. package/dist/components/index.js +21 -13
  25. package/dist/firebase/config.d.ts +34 -0
  26. package/dist/firebase/config.d.ts.map +1 -1
  27. package/dist/hooks/index.cjs +26 -13
  28. package/dist/hooks/index.cjs.map +1 -1
  29. package/dist/hooks/index.d.ts +2 -0
  30. package/dist/hooks/index.d.ts.map +1 -1
  31. package/dist/hooks/index.js +24 -11
  32. package/dist/hooks/useCommonFeatures.d.ts +74 -0
  33. package/dist/hooks/useCommonFeatures.d.ts.map +1 -0
  34. package/dist/hooks/useFeatureFlags.d.ts +134 -0
  35. package/dist/hooks/useFeatureFlags.d.ts.map +1 -0
  36. package/dist/{AnnouncementModal-Bqy0pn3V.cjs → index-Dt5YjYnK.cjs} +209 -14
  37. package/dist/index-Dt5YjYnK.cjs.map +1 -0
  38. package/dist/{AnnouncementModal-sxH4K5gy.js → index-Dv34aG2I.js} +212 -17
  39. package/dist/index-Dv34aG2I.js.map +1 -0
  40. package/dist/index.cjs +125 -60
  41. package/dist/index.cjs.map +1 -1
  42. package/dist/index.d.ts +10 -5
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +173 -108
  45. package/dist/index.js.map +1 -1
  46. package/dist/notifications/index.js +14 -14
  47. package/dist/services/commonFeatures.d.ts +22 -0
  48. package/dist/services/commonFeatures.d.ts.map +1 -0
  49. package/dist/services/featureFlags.d.ts +71 -0
  50. package/dist/services/featureFlags.d.ts.map +1 -0
  51. package/dist/services/index.cjs +49 -17
  52. package/dist/services/index.cjs.map +1 -1
  53. package/dist/services/index.d.ts +2 -0
  54. package/dist/services/index.d.ts.map +1 -1
  55. package/dist/services/index.js +75 -43
  56. package/dist/services/index.js.map +1 -1
  57. package/dist/types/commonFeatures.d.ts +194 -0
  58. package/dist/types/commonFeatures.d.ts.map +1 -0
  59. package/dist/types/featureFlags.d.ts +203 -0
  60. package/dist/types/featureFlags.d.ts.map +1 -0
  61. package/dist/types/index.cjs +15 -0
  62. package/dist/types/index.cjs.map +1 -1
  63. package/dist/types/index.d.ts +3 -1
  64. package/dist/types/index.d.ts.map +1 -1
  65. package/dist/types/index.js +15 -0
  66. package/dist/types/index.js.map +1 -1
  67. package/dist/useCommonFeatures-CgyDq6LZ.js +489 -0
  68. package/dist/useCommonFeatures-CgyDq6LZ.js.map +1 -0
  69. package/dist/useCommonFeatures-DnDlhmri.cjs +488 -0
  70. package/dist/useCommonFeatures-DnDlhmri.cjs.map +1 -0
  71. package/dist/useFeatureFlags-BRJSyH9M.js +368 -0
  72. package/dist/useFeatureFlags-BRJSyH9M.js.map +1 -0
  73. package/dist/useFeatureFlags-DXqBJ5Mh.cjs +367 -0
  74. package/dist/useFeatureFlags-DXqBJ5Mh.cjs.map +1 -0
  75. package/dist/{useNotificationEvents-D8DVxah1.js → useNotificationEvents-DAmR7FYF.js} +14 -14
  76. package/dist/{useNotificationEvents-D8DVxah1.js.map → useNotificationEvents-DAmR7FYF.js.map} +1 -1
  77. package/package.json +15 -8
  78. package/dist/AnnouncementModal-Bqy0pn3V.cjs.map +0 -1
  79. package/dist/AnnouncementModal-sxH4K5gy.js.map +0 -1
  80. package/dist/analytics-40-S_fHC.js +0 -440
  81. package/dist/analytics-40-S_fHC.js.map +0 -1
  82. package/dist/analytics-lEzOx2vl.cjs +0 -461
  83. package/dist/analytics-lEzOx2vl.cjs.map +0 -1
  84. package/dist/useBroadcasts-DzpCcbC8.js +0 -161
  85. package/dist/useBroadcasts-DzpCcbC8.js.map +0 -1
  86. package/dist/useBroadcasts-FP6ZrcY_.cjs +0 -160
  87. package/dist/useBroadcasts-FP6ZrcY_.cjs.map +0 -1
  88. package/dist/useCampaigns-BOZ9dDsG.cjs +0 -152
  89. package/dist/useCampaigns-BOZ9dDsG.cjs.map +0 -1
  90. package/dist/useCampaigns-D46b9zuf.js +0 -153
  91. package/dist/useCampaigns-D46b9zuf.js.map +0 -1
@@ -0,0 +1,74 @@
1
+ import { ContactInfo, DeveloperInfo, AddressInfo, SocialLink, PaymentOption, Service, Skill, Testimonial, UseCommonFeatureOptions, UseCommonFeatureResult, UseCommonFeaturesListResult, FetchSocialLinksOptions, FetchServicesOptions, FetchSkillsOptions, FetchTestimonialsOptions, FetchPaymentOptionsOptions } from '../types/commonFeatures';
2
+ /**
3
+ * Hook to fetch contact information
4
+ *
5
+ * @example
6
+ * ```tsx
7
+ * const { data: contact, loading } = useContactInfo();
8
+ *
9
+ * if (loading) return <Spinner />;
10
+ * if (!contact) return null;
11
+ *
12
+ * return <a href={`mailto:${contact.email}`}>{contact.email}</a>;
13
+ * ```
14
+ */
15
+ export declare function useContactInfo(options?: UseCommonFeatureOptions): UseCommonFeatureResult<ContactInfo>;
16
+ /**
17
+ * Hook to fetch developer information
18
+ *
19
+ * @example
20
+ * ```tsx
21
+ * const { data: developer, loading } = useDeveloperInfo();
22
+ *
23
+ * if (loading) return <Spinner />;
24
+ * if (!developer) return null;
25
+ *
26
+ * return (
27
+ * <div>
28
+ * <h1>{developer.name}</h1>
29
+ * <p>{developer.title}</p>
30
+ * </div>
31
+ * );
32
+ * ```
33
+ */
34
+ export declare function useDeveloperInfo(options?: UseCommonFeatureOptions): UseCommonFeatureResult<DeveloperInfo>;
35
+ /**
36
+ * Hook to fetch address information
37
+ */
38
+ export declare function useAddressInfo(options?: UseCommonFeatureOptions): UseCommonFeatureResult<AddressInfo>;
39
+ /**
40
+ * Hook to fetch social links
41
+ *
42
+ * @example
43
+ * ```tsx
44
+ * const { data: links, loading } = useSocialLinks({ showIn: ['footer'] });
45
+ *
46
+ * if (loading) return <Spinner />;
47
+ *
48
+ * return (
49
+ * <div>
50
+ * {links.map(link => (
51
+ * <a key={link.id} href={link.url}>{link.platform}</a>
52
+ * ))}
53
+ * </div>
54
+ * );
55
+ * ```
56
+ */
57
+ export declare function useSocialLinks(options?: FetchSocialLinksOptions & UseCommonFeatureOptions): UseCommonFeaturesListResult<SocialLink>;
58
+ /**
59
+ * Hook to fetch payment options
60
+ */
61
+ export declare function usePaymentOptions(options?: FetchPaymentOptionsOptions & UseCommonFeatureOptions): UseCommonFeaturesListResult<PaymentOption>;
62
+ /**
63
+ * Hook to fetch services
64
+ */
65
+ export declare function useServices(options?: FetchServicesOptions & UseCommonFeatureOptions): UseCommonFeaturesListResult<Service>;
66
+ /**
67
+ * Hook to fetch skills
68
+ */
69
+ export declare function useSkills(options?: FetchSkillsOptions & UseCommonFeatureOptions): UseCommonFeaturesListResult<Skill>;
70
+ /**
71
+ * Hook to fetch testimonials
72
+ */
73
+ export declare function useTestimonials(options?: FetchTestimonialsOptions & UseCommonFeatureOptions): UseCommonFeaturesListResult<Testimonial>;
74
+ //# sourceMappingURL=useCommonFeatures.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCommonFeatures.d.ts","sourceRoot":"","sources":["../../src/hooks/useCommonFeatures.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAwBH,OAAO,KAAK,EACV,WAAW,EACX,aAAa,EACb,WAAW,EACX,UAAU,EACV,aAAa,EACb,OAAO,EACP,KAAK,EACL,WAAW,EACX,uBAAuB,EACvB,sBAAsB,EACtB,2BAA2B,EAC3B,uBAAuB,EACvB,oBAAoB,EACpB,kBAAkB,EAClB,wBAAwB,EACxB,0BAA0B,EAC3B,MAAM,yBAAyB,CAAC;AAMjC;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAC5B,OAAO,GAAE,uBAA4B,GACpC,sBAAsB,CAAC,WAAW,CAAC,CA2DrC;AAMD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,GAAE,uBAA4B,GACpC,sBAAsB,CAAC,aAAa,CAAC,CA2DvC;AAMD;;GAEG;AACH,wBAAgB,cAAc,CAC5B,OAAO,GAAE,uBAA4B,GACpC,sBAAsB,CAAC,WAAW,CAAC,CA4CrC;AAMD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAC5B,OAAO,GAAE,uBAAuB,GAAG,uBAA4B,GAC9D,2BAA2B,CAAC,UAAU,CAAC,CA4CzC;AAMD;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,GAAE,0BAA0B,GAAG,uBAA4B,GACjE,2BAA2B,CAAC,aAAa,CAAC,CA4C5C;AAMD;;GAEG;AACH,wBAAgB,WAAW,CACzB,OAAO,GAAE,oBAAoB,GAAG,uBAA4B,GAC3D,2BAA2B,CAAC,OAAO,CAAC,CA4CtC;AAMD;;GAEG;AACH,wBAAgB,SAAS,CACvB,OAAO,GAAE,kBAAkB,GAAG,uBAA4B,GACzD,2BAA2B,CAAC,KAAK,CAAC,CA4CpC;AAMD;;GAEG;AACH,wBAAgB,eAAe,CAC7B,OAAO,GAAE,wBAAwB,GAAG,uBAA4B,GAC/D,2BAA2B,CAAC,WAAW,CAAC,CA4C1C"}
@@ -0,0 +1,134 @@
1
+ import { FeatureId, FeatureAvailability, SharedFeaturesStatus, UseFeatureFlagsOptions, UseFeatureFlagsResult } from '../types/featureFlags';
2
+ /**
3
+ * Hook to fetch and monitor feature flags
4
+ *
5
+ * @param options - Hook options
6
+ * @returns Feature flags status and utilities
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * const {
11
+ * status,
12
+ * loading,
13
+ * isFeatureAvailable,
14
+ * hasDeprecatedFeatures
15
+ * } = useFeatureFlags();
16
+ *
17
+ * if (loading) return <Spinner />;
18
+ *
19
+ * if (!status?.operational) {
20
+ * return <MaintenancePage message={status?.maintenanceMessage} />;
21
+ * }
22
+ *
23
+ * if (isFeatureAvailable('contactInfo')) {
24
+ * return <ContactInfo />;
25
+ * }
26
+ * ```
27
+ */
28
+ export declare function useFeatureFlags(options?: UseFeatureFlagsOptions): UseFeatureFlagsResult;
29
+ /**
30
+ * Hook to check a single feature's availability
31
+ *
32
+ * @param featureId - The feature to check
33
+ * @returns Feature availability and loading state
34
+ *
35
+ * @example
36
+ * ```tsx
37
+ * const { available, loading, deprecated } = useFeature('contactInfo');
38
+ *
39
+ * if (loading) return <Spinner />;
40
+ * if (!available) return null;
41
+ *
42
+ * return <ContactInfo />;
43
+ * ```
44
+ */
45
+ export declare function useFeature(featureId: FeatureId): {
46
+ /** Whether the feature is available */
47
+ available: boolean;
48
+ /** Whether the check is in progress */
49
+ loading: boolean;
50
+ /** Full availability details */
51
+ availability: FeatureAvailability | null;
52
+ /** Whether the feature is enabled (but might need upgrade) */
53
+ enabled: boolean;
54
+ /** Whether using a deprecated version */
55
+ deprecated: boolean;
56
+ /** Whether an upgrade is required */
57
+ upgradeRequired: boolean;
58
+ /** Deprecation warning if applicable */
59
+ deprecationWarning: string | undefined;
60
+ /** Reason feature is unavailable */
61
+ unavailableReason: string | undefined;
62
+ };
63
+ /**
64
+ * Hook to subscribe to real-time feature flag updates
65
+ *
66
+ * @param callback - Function to call when flags change
67
+ *
68
+ * @example
69
+ * ```tsx
70
+ * useFeatureFlagsSubscription((flags) => {
71
+ * if (flags?.maintenanceMode) {
72
+ * showMaintenanceBanner();
73
+ * }
74
+ * });
75
+ * ```
76
+ */
77
+ export declare function useFeatureFlagsSubscription(callback: (status: SharedFeaturesStatus | null) => void): void;
78
+ /**
79
+ * Hook to check if shared-features is operational
80
+ *
81
+ * @returns Whether shared-features is operational
82
+ *
83
+ * @example
84
+ * ```tsx
85
+ * const { operational, maintenanceMessage } = useSharedFeaturesOperational();
86
+ *
87
+ * if (!operational) {
88
+ * return <MaintenancePage message={maintenanceMessage} />;
89
+ * }
90
+ * ```
91
+ */
92
+ export declare function useSharedFeaturesOperational(): {
93
+ /** Whether shared-features is operational */
94
+ operational: boolean;
95
+ /** Whether check is in progress */
96
+ loading: boolean;
97
+ /** Maintenance message if in maintenance mode */
98
+ maintenanceMessage: string | undefined;
99
+ /** Whether in maintenance mode */
100
+ maintenanceMode: boolean;
101
+ /** Current API version */
102
+ apiVersion: string;
103
+ };
104
+ /**
105
+ * Hook for conditional rendering based on feature availability
106
+ *
107
+ * @param featureId - The feature to check
108
+ * @returns Object with show/hide helpers
109
+ *
110
+ * @example
111
+ * ```tsx
112
+ * const { shouldRender, FallbackOrChildren } = useFeatureGate('contactInfo');
113
+ *
114
+ * return (
115
+ * <FallbackOrChildren fallback={<OldContactInfo />}>
116
+ * <NewContactInfo />
117
+ * </FallbackOrChildren>
118
+ * );
119
+ * ```
120
+ */
121
+ export declare function useFeatureGate(featureId: FeatureId): {
122
+ /** Whether the feature should be rendered */
123
+ shouldRender: boolean;
124
+ /** Whether still checking availability */
125
+ loading: boolean;
126
+ /** Whether using deprecated version */
127
+ deprecated: boolean;
128
+ /** Component that renders children if available, fallback otherwise */
129
+ FallbackOrChildren: ({ children, fallback, }: {
130
+ children: React.ReactNode;
131
+ fallback?: React.ReactNode;
132
+ }) => import('react').ReactNode;
133
+ };
134
+ //# sourceMappingURL=useFeatureFlags.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFeatureFlags.d.ts","sourceRoot":"","sources":["../../src/hooks/useFeatureFlags.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAWH,OAAO,KAAK,EACV,SAAS,EACT,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EAEtB,MAAM,uBAAuB,CAAC;AAE/B;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,eAAe,CAC7B,OAAO,GAAE,sBAA2B,GACnC,qBAAqB,CAkHvB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,SAAS;IA6C3C,uCAAuC;;IAEvC,uCAAuC;;IAEvC,gCAAgC;;IAEhC,8DAA8D;;IAE9D,yCAAyC;;IAEzC,qCAAqC;;IAErC,wCAAwC;;IAExC,oCAAoC;;EAGvC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,CAAC,MAAM,EAAE,oBAAoB,GAAG,IAAI,KAAK,IAAI,QAuBxD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,4BAA4B;IAIxC,6CAA6C;;IAE7C,mCAAmC;;IAEnC,iDAAiD;;IAEjD,kCAAkC;;IAElC,0BAA0B;;EAG7B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,SAAS;IAY/C,6CAA6C;;IAE7C,0CAA0C;;IAE1C,uCAAuC;;IAEvC,uEAAuE;kDAKlE;QACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;QAC1B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;KAC5B;EAON"}
@@ -3,15 +3,15 @@ const jsxRuntime = require("react/jsx-runtime");
3
3
  const react = require("react");
4
4
  const themes = require("@radix-ui/themes");
5
5
  const reactIcons = require("@radix-ui/react-icons");
6
- const useCampaigns = require("./useCampaigns-BOZ9dDsG.cjs");
6
+ const useCommonFeatures = require("./useCommonFeatures-DnDlhmri.cjs");
7
7
  const lucideReact = require("lucide-react");
8
- const analytics = require("./analytics-lEzOx2vl.cjs");
8
+ const commonFeatures = require("./commonFeatures-CiqxxOin.cjs");
9
9
  function AdPanel({
10
10
  placement,
11
11
  variant: _variant = "small_panel_2",
12
12
  className
13
13
  }) {
14
- const { campaign, loading, error, recordImpression, recordClick, recordClose } = useCampaigns.useCampaign({ placement });
14
+ const { campaign, loading, error, recordImpression, recordClick, recordClose } = useCommonFeatures.useCampaign({ placement });
15
15
  const hasRecordedImpression = react.useRef(false);
16
16
  react.useEffect(() => {
17
17
  if (campaign && !hasRecordedImpression.current) {
@@ -382,7 +382,7 @@ function AdSlider({
382
382
  recordImpression,
383
383
  recordClick,
384
384
  recordClose
385
- } = useCampaigns.useCampaign({ placement });
385
+ } = useCommonFeatures.useCampaign({ placement });
386
386
  react.useEffect(() => {
387
387
  if (campaign && !hasTrackedImpression.current) {
388
388
  hasTrackedImpression.current = true;
@@ -419,14 +419,14 @@ function AdModal({
419
419
  }) {
420
420
  const [dontShowAgain, setDontShowAgain] = react.useState(false);
421
421
  const hasTrackedImpression = react.useRef(false);
422
- const { shouldShow, markAsShown } = useCampaigns.useOneTimeAdModal();
422
+ const { shouldShow, markAsShown } = useCommonFeatures.useOneTimeAdModal();
423
423
  const {
424
424
  campaign,
425
425
  loading,
426
426
  recordImpression,
427
427
  recordClick,
428
428
  recordClose
429
- } = useCampaigns.useCampaign({ placement });
429
+ } = useCommonFeatures.useCampaign({ placement });
430
430
  react.useEffect(() => {
431
431
  if (shouldShow && campaign && !hasTrackedImpression.current) {
432
432
  hasTrackedImpression.current = true;
@@ -446,14 +446,14 @@ function AdModal({
446
446
  markAsShown();
447
447
  onClose?.();
448
448
  }, [campaign, recordClose, markAsShown, onClose]);
449
- if (!analytics.isInitialized()) {
449
+ if (!commonFeatures.isInitialized()) {
450
450
  return null;
451
451
  }
452
452
  if (!shouldShow || loading) {
453
453
  return null;
454
454
  }
455
455
  if (!campaign) {
456
- const config = analytics.getConfig();
456
+ const config = commonFeatures.getConfig();
457
457
  const defaultTitle = welcomeTitle || `Welcome to ${config.projectName}!`;
458
458
  const defaultDesc = welcomeDescription || "Discover amazing features and tools at your fingertips.";
459
459
  return /* @__PURE__ */ jsxRuntime.jsx(themes.Dialog.Root, { open: true, onOpenChange: (open) => !open && handleClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(themes.Dialog.Content, { style: { maxWidth: 450 }, children: [
@@ -977,14 +977,14 @@ function AdUpdateModal({
977
977
  const [currentIndex, setCurrentIndex] = react.useState(0);
978
978
  const autoAdvanceRef = react.useRef(null);
979
979
  const trackedImpressions = react.useRef(/* @__PURE__ */ new Set());
980
- const { shouldShow, currentVersion, markAsShown } = useCampaigns.useUpdateAdModal();
980
+ const { shouldShow, currentVersion, markAsShown } = useCommonFeatures.useUpdateAdModal();
981
981
  const {
982
982
  campaigns,
983
983
  loading,
984
984
  recordImpression,
985
985
  recordClick,
986
986
  recordClose
987
- } = useCampaigns.useCampaigns({ placement, maxCampaigns });
987
+ } = useCommonFeatures.useCampaigns({ placement, maxCampaigns });
988
988
  react.useEffect(() => {
989
989
  if (shouldShow && campaigns.length > 0 && currentIndex < campaigns.length) {
990
990
  const campaign = campaigns[currentIndex];
@@ -1184,7 +1184,7 @@ function AdBanner({
1184
1184
  loading,
1185
1185
  recordImpression,
1186
1186
  recordClick
1187
- } = useCampaigns.useCampaigns({ placement, maxCampaigns });
1187
+ } = useCommonFeatures.useCampaigns({ placement, maxCampaigns });
1188
1188
  react.useEffect(() => {
1189
1189
  if (campaigns.length === 0) return;
1190
1190
  const campaign2 = campaigns[currentIndex];
@@ -1480,7 +1480,7 @@ function BroadcastBanner({
1480
1480
  const handleDismiss = react.useCallback(() => {
1481
1481
  onDismiss?.();
1482
1482
  }, [onDismiss]);
1483
- if (!analytics.isInitialized()) {
1483
+ if (!commonFeatures.isInitialized()) {
1484
1484
  return null;
1485
1485
  }
1486
1486
  const typeStyle = TYPE_STYLES[broadcast.type] || TYPE_STYLES.info;
@@ -1690,7 +1690,7 @@ function AnnouncementModal({
1690
1690
  const handleClose = react.useCallback(() => {
1691
1691
  onClose();
1692
1692
  }, [onClose]);
1693
- if (!analytics.isInitialized() || !broadcast) {
1693
+ if (!commonFeatures.isInitialized() || !broadcast) {
1694
1694
  return null;
1695
1695
  }
1696
1696
  const typeConfig = TYPE_CONFIG[broadcast.type] || TYPE_CONFIG.announcement;
@@ -1830,26 +1830,221 @@ function AnnouncementModal({
1830
1830
  }
1831
1831
  ) });
1832
1832
  }
1833
+ const socialIcons = {
1834
+ github: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Github, { size: 18 }),
1835
+ linkedin: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Linkedin, { size: 18 }),
1836
+ twitter: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Twitter, { size: 18 }),
1837
+ facebook: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Globe, { size: 18 }),
1838
+ instagram: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Globe, { size: 18 }),
1839
+ youtube: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Globe, { size: 18 }),
1840
+ tiktok: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Globe, { size: 18 }),
1841
+ discord: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageCircle, { size: 18 }),
1842
+ telegram: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageCircle, { size: 18 }),
1843
+ whatsapp: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageCircle, { size: 18 }),
1844
+ medium: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Globe, { size: 18 }),
1845
+ devto: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Code, { size: 18 }),
1846
+ stackoverflow: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Code, { size: 18 }),
1847
+ dribbble: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Globe, { size: 18 }),
1848
+ behance: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Globe, { size: 18 }),
1849
+ codepen: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Code, { size: 18 }),
1850
+ npm: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Code, { size: 18 }),
1851
+ website: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Globe, { size: 18 }),
1852
+ email: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Mail, { size: 18 }),
1853
+ other: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { size: 18 })
1854
+ };
1855
+ function ContactCard({ data: propData, compact = false, showFreelance = true }) {
1856
+ const { data: hookData, loading } = useCommonFeatures.useContactInfo({ autoFetch: !propData });
1857
+ const data = propData ?? hookData;
1858
+ if (loading) return /* @__PURE__ */ jsxRuntime.jsx(ContactCardSkeleton, {});
1859
+ if (!data) return null;
1860
+ return /* @__PURE__ */ jsxRuntime.jsx(themes.Card, { size: compact ? "1" : "2", children: /* @__PURE__ */ jsxRuntime.jsxs(themes.Flex, { direction: "column", gap: "3", children: [
1861
+ /* @__PURE__ */ jsxRuntime.jsx(themes.Text, { size: "3", weight: "bold", children: "Contact" }),
1862
+ showFreelance && data.freelanceAvailable && /* @__PURE__ */ jsxRuntime.jsx(themes.Badge, { color: "green", size: "1", children: "Available for Freelance" }),
1863
+ /* @__PURE__ */ jsxRuntime.jsxs(themes.Flex, { direction: "column", gap: "2", children: [
1864
+ data.email && /* @__PURE__ */ jsxRuntime.jsx(themes.Link, { href: `mailto:${data.email}`, size: "2", children: /* @__PURE__ */ jsxRuntime.jsxs(themes.Flex, { align: "center", gap: "2", children: [
1865
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Mail, { size: 16 }),
1866
+ /* @__PURE__ */ jsxRuntime.jsx(themes.Text, { children: data.email })
1867
+ ] }) }),
1868
+ data.phone && /* @__PURE__ */ jsxRuntime.jsx(themes.Link, { href: `tel:${data.phone}`, size: "2", children: /* @__PURE__ */ jsxRuntime.jsxs(themes.Flex, { align: "center", gap: "2", children: [
1869
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Phone, { size: 16 }),
1870
+ /* @__PURE__ */ jsxRuntime.jsx(themes.Text, { children: data.phone })
1871
+ ] }) }),
1872
+ data.whatsapp && /* @__PURE__ */ jsxRuntime.jsx(themes.Link, { href: `https://wa.me/${data.whatsapp.replace(/\D/g, "")}`, target: "_blank", size: "2", children: /* @__PURE__ */ jsxRuntime.jsxs(themes.Flex, { align: "center", gap: "2", children: [
1873
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageCircle, { size: 16 }),
1874
+ /* @__PURE__ */ jsxRuntime.jsx(themes.Text, { children: "WhatsApp" })
1875
+ ] }) })
1876
+ ] }),
1877
+ !compact && data.workingHours && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1878
+ /* @__PURE__ */ jsxRuntime.jsx(themes.Separator, { size: "4" }),
1879
+ /* @__PURE__ */ jsxRuntime.jsx(themes.Text, { size: "1", color: "gray", children: data.workingHours })
1880
+ ] })
1881
+ ] }) });
1882
+ }
1883
+ function ContactCardSkeleton() {
1884
+ return /* @__PURE__ */ jsxRuntime.jsx(themes.Card, { children: /* @__PURE__ */ jsxRuntime.jsxs(themes.Flex, { direction: "column", gap: "3", children: [
1885
+ /* @__PURE__ */ jsxRuntime.jsx(themes.Box, { style: { height: 20, width: 80, background: "var(--gray-4)", borderRadius: 4 } }),
1886
+ /* @__PURE__ */ jsxRuntime.jsx(themes.Box, { style: { height: 16, width: 180, background: "var(--gray-3)", borderRadius: 4 } }),
1887
+ /* @__PURE__ */ jsxRuntime.jsx(themes.Box, { style: { height: 16, width: 120, background: "var(--gray-3)", borderRadius: 4 } })
1888
+ ] }) });
1889
+ }
1890
+ function DeveloperCard({ data: propData, compact = false, showBio = true }) {
1891
+ const { data: hookData, loading } = useCommonFeatures.useDeveloperInfo({ autoFetch: !propData });
1892
+ const data = propData ?? hookData;
1893
+ if (loading) return /* @__PURE__ */ jsxRuntime.jsx(DeveloperCardSkeleton, {});
1894
+ if (!data) return null;
1895
+ return /* @__PURE__ */ jsxRuntime.jsx(themes.Card, { size: compact ? "1" : "2", children: /* @__PURE__ */ jsxRuntime.jsxs(themes.Flex, { direction: "column", gap: "3", children: [
1896
+ /* @__PURE__ */ jsxRuntime.jsxs(themes.Flex, { align: "center", gap: "3", children: [
1897
+ data.avatar && /* @__PURE__ */ jsxRuntime.jsx(themes.Avatar, { src: data.avatar, fallback: data.name?.[0] || "?", size: "4", radius: "full" }),
1898
+ /* @__PURE__ */ jsxRuntime.jsxs(themes.Box, { children: [
1899
+ /* @__PURE__ */ jsxRuntime.jsx(themes.Text, { size: "4", weight: "bold", children: data.name }),
1900
+ /* @__PURE__ */ jsxRuntime.jsx(themes.Text, { size: "2", color: "gray", children: data.title })
1901
+ ] })
1902
+ ] }),
1903
+ data.availableForHire && /* @__PURE__ */ jsxRuntime.jsx(themes.Badge, { color: "green", size: "1", children: "Available for Hire" }),
1904
+ showBio && !compact && data.bio && /* @__PURE__ */ jsxRuntime.jsx(themes.Text, { size: "2", color: "gray", children: data.shortBio || data.bio }),
1905
+ /* @__PURE__ */ jsxRuntime.jsxs(themes.Flex, { gap: "2", wrap: "wrap", children: [
1906
+ data.website && /* @__PURE__ */ jsxRuntime.jsx(themes.Link, { href: data.website, target: "_blank", size: "1", children: /* @__PURE__ */ jsxRuntime.jsxs(themes.Flex, { align: "center", gap: "1", children: [
1907
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Globe, { size: 14 }),
1908
+ "Website"
1909
+ ] }) }),
1910
+ data.github && /* @__PURE__ */ jsxRuntime.jsx(themes.Link, { href: data.github, target: "_blank", size: "1", children: /* @__PURE__ */ jsxRuntime.jsxs(themes.Flex, { align: "center", gap: "1", children: [
1911
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Github, { size: 14 }),
1912
+ "GitHub"
1913
+ ] }) }),
1914
+ data.linkedin && /* @__PURE__ */ jsxRuntime.jsx(themes.Link, { href: data.linkedin, target: "_blank", size: "1", children: /* @__PURE__ */ jsxRuntime.jsxs(themes.Flex, { align: "center", gap: "1", children: [
1915
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Linkedin, { size: 14 }),
1916
+ "LinkedIn"
1917
+ ] }) })
1918
+ ] })
1919
+ ] }) });
1920
+ }
1921
+ function DeveloperCardSkeleton() {
1922
+ return /* @__PURE__ */ jsxRuntime.jsx(themes.Card, { children: /* @__PURE__ */ jsxRuntime.jsxs(themes.Flex, { align: "center", gap: "3", children: [
1923
+ /* @__PURE__ */ jsxRuntime.jsx(themes.Box, { style: { height: 48, width: 48, background: "var(--gray-4)", borderRadius: "50%" } }),
1924
+ /* @__PURE__ */ jsxRuntime.jsxs(themes.Box, { children: [
1925
+ /* @__PURE__ */ jsxRuntime.jsx(themes.Box, { style: { height: 20, width: 120, background: "var(--gray-4)", borderRadius: 4, marginBottom: 4 } }),
1926
+ /* @__PURE__ */ jsxRuntime.jsx(themes.Box, { style: { height: 16, width: 80, background: "var(--gray-3)", borderRadius: 4 } })
1927
+ ] })
1928
+ ] }) });
1929
+ }
1930
+ function SocialLinksBar({ data: propData, showIn, gap = "3" }) {
1931
+ const { data: hookData, loading } = useCommonFeatures.useSocialLinks({ autoFetch: !propData, showIn });
1932
+ const data = propData ?? hookData;
1933
+ if (loading || data.length === 0) return null;
1934
+ return /* @__PURE__ */ jsxRuntime.jsx(themes.Flex, { gap, align: "center", wrap: "wrap", children: data.map((link) => /* @__PURE__ */ jsxRuntime.jsx(
1935
+ themes.Link,
1936
+ {
1937
+ href: link.url,
1938
+ target: "_blank",
1939
+ title: link.displayName || link.platform,
1940
+ style: { color: "inherit" },
1941
+ children: socialIcons[link.platform]
1942
+ },
1943
+ link.id
1944
+ )) });
1945
+ }
1946
+ function AddressCard({ data: propData, compact = false }) {
1947
+ const { data: hookData, loading } = useCommonFeatures.useAddressInfo({ autoFetch: !propData });
1948
+ const data = propData ?? hookData;
1949
+ if (loading || !data) return null;
1950
+ const address = data.fullAddress || [data.streetAddress, data.city, data.state, data.country].filter(Boolean).join(", ");
1951
+ return /* @__PURE__ */ jsxRuntime.jsx(themes.Card, { size: compact ? "1" : "2", children: /* @__PURE__ */ jsxRuntime.jsxs(themes.Flex, { align: "start", gap: "2", children: [
1952
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MapPin, { size: 18, style: { flexShrink: 0, marginTop: 2 } }),
1953
+ /* @__PURE__ */ jsxRuntime.jsxs(themes.Box, { children: [
1954
+ data.label && /* @__PURE__ */ jsxRuntime.jsx(themes.Text, { size: "2", weight: "bold", children: data.label }),
1955
+ /* @__PURE__ */ jsxRuntime.jsx(themes.Text, { size: "2", color: "gray", children: address }),
1956
+ data.googleMapsUrl && /* @__PURE__ */ jsxRuntime.jsx(themes.Link, { href: data.googleMapsUrl, target: "_blank", size: "1", children: "View on Maps" })
1957
+ ] })
1958
+ ] }) });
1959
+ }
1960
+ function SkillsDisplay({ data: propData, featuredOnly = false, showLevel = true, maxItems }) {
1961
+ const { data: hookData, loading } = useCommonFeatures.useSkills({ autoFetch: !propData, featuredOnly });
1962
+ let data = propData ?? hookData;
1963
+ if (maxItems && data.length > maxItems) {
1964
+ data = data.slice(0, maxItems);
1965
+ }
1966
+ if (loading || data.length === 0) return null;
1967
+ const levelColors = {
1968
+ beginner: "gray",
1969
+ intermediate: "blue",
1970
+ advanced: "green",
1971
+ expert: "orange"
1972
+ };
1973
+ return /* @__PURE__ */ jsxRuntime.jsx(themes.Flex, { gap: "2", wrap: "wrap", children: data.map((skill) => /* @__PURE__ */ jsxRuntime.jsx(themes.Badge, { color: showLevel ? levelColors[skill.level] : void 0, size: "2", children: skill.name }, skill.id)) });
1974
+ }
1975
+ function TestimonialsGrid({ data: propData, featuredOnly = false, maxItems, columns = "2" }) {
1976
+ const { data: hookData, loading } = useCommonFeatures.useTestimonials({ autoFetch: !propData, featuredOnly, limit: maxItems });
1977
+ const data = propData ?? hookData;
1978
+ if (loading || data.length === 0) return null;
1979
+ return /* @__PURE__ */ jsxRuntime.jsx(themes.Grid, { columns, gap: "4", children: data.map((testimonial) => /* @__PURE__ */ jsxRuntime.jsx(themes.Card, { children: /* @__PURE__ */ jsxRuntime.jsxs(themes.Flex, { direction: "column", gap: "3", children: [
1980
+ testimonial.rating && /* @__PURE__ */ jsxRuntime.jsx(themes.Flex, { gap: "1", children: Array.from({ length: testimonial.rating }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Star, { size: 14, fill: "var(--amber-9)", color: "var(--amber-9)" }, i)) }),
1981
+ /* @__PURE__ */ jsxRuntime.jsxs(themes.Text, { size: "2", style: { fontStyle: "italic" }, children: [
1982
+ '"',
1983
+ testimonial.shortContent || testimonial.content,
1984
+ '"'
1985
+ ] }),
1986
+ /* @__PURE__ */ jsxRuntime.jsxs(themes.Flex, { align: "center", gap: "2", children: [
1987
+ testimonial.authorAvatar && /* @__PURE__ */ jsxRuntime.jsx(themes.Avatar, { src: testimonial.authorAvatar, fallback: testimonial.authorName?.[0] || "?", size: "2", radius: "full" }),
1988
+ /* @__PURE__ */ jsxRuntime.jsxs(themes.Box, { children: [
1989
+ /* @__PURE__ */ jsxRuntime.jsx(themes.Text, { size: "2", weight: "bold", children: testimonial.authorName }),
1990
+ (testimonial.authorTitle || testimonial.authorCompany) && /* @__PURE__ */ jsxRuntime.jsx(themes.Text, { size: "1", color: "gray", children: [testimonial.authorTitle, testimonial.authorCompany].filter(Boolean).join(" at ") })
1991
+ ] })
1992
+ ] })
1993
+ ] }) }, testimonial.id)) });
1994
+ }
1995
+ function ServicesGrid({ data: propData, featuredOnly = false, maxItems, columns = "3" }) {
1996
+ const { data: hookData, loading } = useCommonFeatures.useServices({ autoFetch: !propData, featuredOnly });
1997
+ let data = propData ?? hookData;
1998
+ if (maxItems && data.length > maxItems) {
1999
+ data = data.slice(0, maxItems);
2000
+ }
2001
+ if (loading || data.length === 0) return null;
2002
+ return /* @__PURE__ */ jsxRuntime.jsx(themes.Grid, { columns, gap: "4", children: data.map((service) => /* @__PURE__ */ jsxRuntime.jsx(themes.Card, { children: /* @__PURE__ */ jsxRuntime.jsxs(themes.Flex, { direction: "column", gap: "2", children: [
2003
+ /* @__PURE__ */ jsxRuntime.jsxs(themes.Flex, { align: "center", gap: "2", children: [
2004
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Briefcase, { size: 18 }),
2005
+ /* @__PURE__ */ jsxRuntime.jsx(themes.Text, { size: "3", weight: "bold", children: service.title })
2006
+ ] }),
2007
+ /* @__PURE__ */ jsxRuntime.jsx(themes.Text, { size: "2", color: "gray", children: service.shortDescription || service.description }),
2008
+ service.technologies && service.technologies.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(themes.Flex, { gap: "1", wrap: "wrap", children: service.technologies.slice(0, 5).map((tech, i) => /* @__PURE__ */ jsxRuntime.jsx(themes.Badge, { size: "1", color: "gray", children: tech }, i)) })
2009
+ ] }) }, service.id)) });
2010
+ }
2011
+ function FooterSection({ showContact = true, showSocialLinks = true, showAddress = false }) {
2012
+ return /* @__PURE__ */ jsxRuntime.jsxs(themes.Flex, { direction: "column", gap: "4", align: "center", children: [
2013
+ showSocialLinks && /* @__PURE__ */ jsxRuntime.jsx(SocialLinksBar, { showIn: ["footer"] }),
2014
+ /* @__PURE__ */ jsxRuntime.jsxs(themes.Flex, { gap: "4", wrap: "wrap", justify: "center", children: [
2015
+ showContact && /* @__PURE__ */ jsxRuntime.jsx(ContactCard, { compact: true }),
2016
+ showAddress && /* @__PURE__ */ jsxRuntime.jsx(AddressCard, { compact: true })
2017
+ ] })
2018
+ ] });
2019
+ }
1833
2020
  exports.AdBanner = AdBanner;
1834
2021
  exports.AdModal = AdModal;
1835
2022
  exports.AdPanel = AdPanel;
1836
2023
  exports.AdSlider = AdSlider;
1837
2024
  exports.AdUpdateModal = AdUpdateModal;
2025
+ exports.AddressCard = AddressCard;
1838
2026
  exports.AnnouncementModal = AnnouncementModal;
1839
2027
  exports.BroadcastBanner = BroadcastBanner;
1840
2028
  exports.BroadcastBanners = BroadcastBanners;
1841
2029
  exports.CardVariant = CardVariant;
1842
2030
  exports.ComparisonVariant = ComparisonVariant;
2031
+ exports.ContactCard = ContactCard;
2032
+ exports.DeveloperCard = DeveloperCard;
1843
2033
  exports.FeatureGridVariant = FeatureGridVariant;
1844
2034
  exports.FeaturesVariant = FeaturesVariant;
2035
+ exports.FooterSection = FooterSection;
1845
2036
  exports.GradientVariant = GradientVariant;
1846
2037
  exports.HeroVariant = HeroVariant;
1847
2038
  exports.LARGE_PANEL_VARIANTS = LARGE_PANEL_VARIANTS;
1848
2039
  exports.MinimalVariant = MinimalVariant;
1849
2040
  exports.SMALL_PANEL_VARIANTS = SMALL_PANEL_VARIANTS;
2041
+ exports.ServicesGrid = ServicesGrid;
2042
+ exports.SkillsDisplay = SkillsDisplay;
2043
+ exports.SocialLinksBar = SocialLinksBar;
1850
2044
  exports.TaglineVariant = TaglineVariant;
1851
2045
  exports.TestimonialVariant = TestimonialVariant;
2046
+ exports.TestimonialsGrid = TestimonialsGrid;
1852
2047
  exports.VideoVariant = VideoVariant;
1853
2048
  exports.getLargePanelVariant = getLargePanelVariant;
1854
2049
  exports.getSmallPanelVariant = getSmallPanelVariant;
1855
- //# sourceMappingURL=AnnouncementModal-Bqy0pn3V.cjs.map
2050
+ //# sourceMappingURL=index-Dt5YjYnK.cjs.map