@uptrademedia/site-kit 1.0.1 → 1.0.4

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 (159) hide show
  1. package/dist/SetupWizard-Cki06kB0.d.mts +12 -0
  2. package/dist/SetupWizard-Cki06kB0.d.ts +12 -0
  3. package/dist/analytics/index.d.mts +87 -0
  4. package/dist/analytics/index.d.ts +87 -0
  5. package/dist/blog/index.d.mts +24 -0
  6. package/dist/blog/index.d.ts +24 -0
  7. package/dist/blog/index.js.map +1 -1
  8. package/dist/blog/index.mjs.map +1 -1
  9. package/dist/chunk-2IHTEKHU.mjs +332 -0
  10. package/dist/chunk-2IHTEKHU.mjs.map +1 -0
  11. package/dist/chunk-5R4R3WDP.js +1451 -0
  12. package/dist/chunk-5R4R3WDP.js.map +1 -0
  13. package/dist/{chunk-RV7H3I6J.js → chunk-ADHVEFWD.js} +68 -2
  14. package/dist/chunk-ADHVEFWD.js.map +1 -0
  15. package/dist/chunk-BGJLOJ7T.mjs +605 -0
  16. package/dist/chunk-BGJLOJ7T.mjs.map +1 -0
  17. package/dist/chunk-BZBJVG5Y.js +88 -0
  18. package/dist/chunk-BZBJVG5Y.js.map +1 -0
  19. package/dist/{chunk-COI6GOX2.mjs → chunk-DOHML47I.mjs} +3 -3
  20. package/dist/chunk-DOHML47I.mjs.map +1 -0
  21. package/dist/chunk-DRFTRTKV.js +809 -0
  22. package/dist/chunk-DRFTRTKV.js.map +1 -0
  23. package/dist/chunk-EL5QTAA3.mjs +805 -0
  24. package/dist/chunk-EL5QTAA3.mjs.map +1 -0
  25. package/dist/chunk-GAJLEDRD.js +334 -0
  26. package/dist/chunk-GAJLEDRD.js.map +1 -0
  27. package/dist/{chunk-3MUOUXHV.js → chunk-K2HWVOEO.js} +3 -3
  28. package/dist/chunk-K2HWVOEO.js.map +1 -0
  29. package/dist/chunk-O2OHHBUD.js +997 -0
  30. package/dist/chunk-O2OHHBUD.js.map +1 -0
  31. package/dist/chunk-QAYJV4KK.js +608 -0
  32. package/dist/chunk-QAYJV4KK.js.map +1 -0
  33. package/dist/{chunk-FEBYQGY4 2.mjs → chunk-SMUFNQLM.mjs} +67 -3
  34. package/dist/chunk-SMUFNQLM.mjs.map +1 -0
  35. package/dist/chunk-VDMZZL2O.mjs +83 -0
  36. package/dist/chunk-VDMZZL2O.mjs.map +1 -0
  37. package/dist/chunk-XFRPT5ZX.mjs +1449 -0
  38. package/dist/chunk-XFRPT5ZX.mjs.map +1 -0
  39. package/dist/chunk-XQJX252G.mjs +981 -0
  40. package/dist/chunk-XQJX252G.mjs.map +1 -0
  41. package/dist/commerce/index.d.mts +168 -0
  42. package/dist/commerce/index.d.ts +168 -0
  43. package/dist/commerce/index.js +38 -38
  44. package/dist/commerce/index.mjs +1 -1
  45. package/dist/commerce/server.d.mts +98 -0
  46. package/dist/commerce/server.d.ts +98 -0
  47. package/dist/engage/index.d.mts +27 -0
  48. package/dist/engage/index.d.ts +27 -0
  49. package/dist/engage/index.js +7 -40
  50. package/dist/engage/index.js.map +1 -1
  51. package/dist/engage/index.mjs +1 -41
  52. package/dist/engage/index.mjs.map +1 -1
  53. package/dist/forms/index.d.mts +437 -0
  54. package/dist/forms/index.d.ts +437 -0
  55. package/dist/forms/index.js +13 -5
  56. package/dist/forms/index.js.map +1 -1
  57. package/dist/forms/index.mjs +2 -2
  58. package/dist/forms/index.mjs.map +1 -1
  59. package/dist/{generators-7Y5ABRYV 2.mjs → generators-TO2FKJR6.mjs} +134 -3
  60. package/dist/generators-TO2FKJR6.mjs.map +1 -0
  61. package/dist/{generators-GWIYCA5M.js → generators-YZWIGHCO.js} +135 -2
  62. package/dist/generators-YZWIGHCO.js.map +1 -0
  63. package/dist/images/index.d.mts +133 -0
  64. package/dist/images/index.d.ts +133 -0
  65. package/dist/images/index.js +41 -0
  66. package/dist/images/index.js.map +1 -0
  67. package/dist/images/index.mjs +8 -0
  68. package/dist/images/index.mjs.map +1 -0
  69. package/dist/index.d.mts +649 -0
  70. package/dist/index.d.ts +649 -0
  71. package/dist/index.js +1355 -104
  72. package/dist/index.js.map +1 -1
  73. package/dist/index.mjs +1242 -76
  74. package/dist/index.mjs.map +1 -1
  75. package/dist/redirects/index.d.mts +72 -0
  76. package/dist/redirects/index.d.ts +72 -0
  77. package/dist/redirects/index.js +25 -0
  78. package/dist/redirects/index.js.map +1 -0
  79. package/dist/redirects/index.mjs +4 -0
  80. package/dist/redirects/index.mjs.map +1 -0
  81. package/dist/routing-BWjUF7lp.d.ts +105 -0
  82. package/dist/routing-CgmRi9tD.d.mts +105 -0
  83. package/dist/{scanner-MF7P3CDE 2.mjs → scanner-AZV5I6US.mjs} +123 -4
  84. package/dist/scanner-AZV5I6US.mjs.map +1 -0
  85. package/dist/{scanner-NT6YG4TD 2.js → scanner-ETJAMIT7.js} +124 -3
  86. package/dist/scanner-ETJAMIT7.js.map +1 -0
  87. package/dist/seo/index.d.mts +273 -0
  88. package/dist/seo/index.d.ts +273 -0
  89. package/dist/seo/server.d.mts +89 -0
  90. package/dist/seo/server.d.ts +89 -0
  91. package/dist/setup/client.d.mts +60 -0
  92. package/dist/setup/client.d.ts +60 -0
  93. package/dist/setup/client.js +30 -0
  94. package/dist/setup/client.js.map +1 -0
  95. package/dist/setup/client.mjs +5 -0
  96. package/dist/setup/client.mjs.map +1 -0
  97. package/dist/setup/index.d.mts +5 -0
  98. package/dist/setup/index.d.ts +5 -0
  99. package/dist/setup/index.js +28 -1043
  100. package/dist/setup/index.js.map +1 -1
  101. package/dist/setup/index.mjs +3 -1043
  102. package/dist/setup/index.mjs.map +1 -1
  103. package/dist/setup/server.d.mts +14 -0
  104. package/dist/setup/server.d.ts +14 -0
  105. package/dist/setup/server.js +13 -0
  106. package/dist/setup/server.js.map +1 -0
  107. package/dist/setup/server.mjs +4 -0
  108. package/dist/setup/server.mjs.map +1 -0
  109. package/dist/sitemap/index.d.mts +78 -0
  110. package/dist/sitemap/index.d.ts +78 -0
  111. package/dist/types-BDojCvvL.d.mts +156 -0
  112. package/dist/types-BDojCvvL.d.ts +156 -0
  113. package/dist/types-BmzutFwy.d.mts +227 -0
  114. package/dist/types-BmzutFwy.d.ts +227 -0
  115. package/dist/types-C0pJGfbH.d.mts +155 -0
  116. package/dist/types-C0pJGfbH.d.ts +155 -0
  117. package/dist/types-DA_Kocle.d.mts +127 -0
  118. package/dist/types-DA_Kocle.d.ts +127 -0
  119. package/dist/types-lFLKKn0G.d.mts +163 -0
  120. package/dist/types-lFLKKn0G.d.ts +163 -0
  121. package/dist/types-nB206tPK.d.mts +309 -0
  122. package/dist/types-nB206tPK.d.ts +309 -0
  123. package/dist/useEventModal-6U1pF3_g.d.mts +209 -0
  124. package/dist/useEventModal-BA8g-1-P.d.ts +209 -0
  125. package/package.json +21 -1
  126. package/dist/chunk-3MUOUXHV.js.map +0 -1
  127. package/dist/chunk-4HVYXYQL 2.mjs +0 -255
  128. package/dist/chunk-4HVYXYQL.mjs +0 -255
  129. package/dist/chunk-4HVYXYQL.mjs.map +0 -1
  130. package/dist/chunk-COI6GOX2.mjs.map +0 -1
  131. package/dist/chunk-EQCVQC35.js 2.map +0 -1
  132. package/dist/chunk-FEBYQGY4.mjs +0 -251
  133. package/dist/chunk-FEBYQGY4.mjs.map +0 -1
  134. package/dist/chunk-NYKRE2FL 2.mjs +0 -31
  135. package/dist/chunk-NYKRE2FL.mjs 2.map +0 -1
  136. package/dist/chunk-RV7H3I6J.js 2.map +0 -1
  137. package/dist/chunk-RV7H3I6J.js.map +0 -1
  138. package/dist/chunk-TUKGA3UK.js +0 -257
  139. package/dist/chunk-TUKGA3UK.js 2.map +0 -1
  140. package/dist/chunk-TUKGA3UK.js.map +0 -1
  141. package/dist/generators-7Y5ABRYV.mjs +0 -161
  142. package/dist/generators-7Y5ABRYV.mjs 2.map +0 -1
  143. package/dist/generators-7Y5ABRYV.mjs.map +0 -1
  144. package/dist/generators-GWIYCA5M.js 2.map +0 -1
  145. package/dist/generators-GWIYCA5M.js.map +0 -1
  146. package/dist/index 2.mjs +0 -74
  147. package/dist/index.js 2.map +0 -1
  148. package/dist/migrator-V6KS75EA 2.mjs +0 -265
  149. package/dist/migrator-V6KS75EA.mjs 2.map +0 -1
  150. package/dist/migrator-XKM7YQCY.js 2.map +0 -1
  151. package/dist/scanner-MF7P3CDE.mjs +0 -14386
  152. package/dist/scanner-MF7P3CDE.mjs 2.map +0 -1
  153. package/dist/scanner-MF7P3CDE.mjs.map +0 -1
  154. package/dist/scanner-NT6YG4TD.js +0 -14397
  155. package/dist/scanner-NT6YG4TD.js 2.map +0 -1
  156. package/dist/scanner-NT6YG4TD.js.map +0 -1
  157. package/dist/web-vitals-BH55V7EJ.js 2.map +0 -1
  158. package/dist/web-vitals-RJYPWAR3 2.mjs +0 -241
  159. package/dist/web-vitals-RJYPWAR3.mjs 2.map +0 -1
@@ -0,0 +1,12 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface SetupWizardProps {
4
+ config?: {
5
+ url?: string;
6
+ anonKey?: string;
7
+ portalApiUrl?: string;
8
+ };
9
+ }
10
+ declare function SetupWizard({ config }?: SetupWizardProps): react_jsx_runtime.JSX.Element;
11
+
12
+ export { SetupWizard as S };
@@ -0,0 +1,12 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface SetupWizardProps {
4
+ config?: {
5
+ url?: string;
6
+ anonKey?: string;
7
+ portalApiUrl?: string;
8
+ };
9
+ }
10
+ declare function SetupWizard({ config }?: SetupWizardProps): react_jsx_runtime.JSX.Element;
11
+
12
+ export { SetupWizard as S };
@@ -0,0 +1,87 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React__default from 'react';
3
+ import { A as AnalyticsContextValue, T as TrackEventOptions, a as TrackConversionOptions } from '../types-DA_Kocle.mjs';
4
+ export { c as AnalyticsConfig, b as AnalyticsEvent, C as Conversion, P as PageView, S as Session, W as WebVitalsData } from '../types-DA_Kocle.mjs';
5
+
6
+ interface AnalyticsProviderProps {
7
+ children: React__default.ReactNode;
8
+ apiUrl?: string;
9
+ apiKey?: string;
10
+ trackPageViews?: boolean;
11
+ trackWebVitals?: boolean;
12
+ trackScrollDepth?: boolean;
13
+ trackClicks?: boolean;
14
+ trackJourneys?: boolean;
15
+ sessionTimeout?: number;
16
+ excludePaths?: string[];
17
+ validateAgainstSitemap?: boolean;
18
+ debug?: boolean;
19
+ }
20
+ declare function AnalyticsProvider({ children, apiUrl: propApiUrl, apiKey: propApiKey, trackPageViews, trackWebVitals, trackScrollDepth, trackClicks, trackJourneys, // NEW: Enable journey tracking by default
21
+ sessionTimeout, excludePaths, validateAgainstSitemap, debug, }: AnalyticsProviderProps): react_jsx_runtime.JSX.Element;
22
+ declare function useAnalytics(): AnalyticsContextValue;
23
+ declare function useTrackEvent(): {
24
+ trackEvent: (options: TrackEventOptions) => void;
25
+ trackConversion: (options: TrackConversionOptions) => void;
26
+ };
27
+
28
+ /**
29
+ * @uptrade/site-kit/analytics - Web Vitals Component
30
+ *
31
+ * Automatically reports Core Web Vitals via Portal API
32
+ */
33
+ interface WebVitalsProps {
34
+ apiUrl?: string;
35
+ apiKey?: string;
36
+ debug?: boolean;
37
+ }
38
+ declare function WebVitals({ apiUrl: propApiUrl, apiKey: propApiKey, debug }: WebVitalsProps): null;
39
+
40
+ /**
41
+ * @uptrade/site-kit/analytics - Contact Tracking Hook
42
+ *
43
+ * Tracks phone calls and email clicks as conversions.
44
+ * Use this hook to automatically track tel: and mailto: links,
45
+ * or manually track contact interactions.
46
+ */
47
+ interface UseContactTrackingOptions {
48
+ /** Automatically track all tel: and mailto: links (default: true) */
49
+ autoTrack?: boolean;
50
+ /** Debug mode - logs events to console */
51
+ debug?: boolean;
52
+ }
53
+ interface ContactTrackingReturn {
54
+ /** Manually track a phone call click */
55
+ trackPhoneClick: (phoneNumber: string, metadata?: Record<string, unknown>) => void;
56
+ /** Manually track an email click */
57
+ trackEmailClick: (email: string, metadata?: Record<string, unknown>) => void;
58
+ }
59
+ /**
60
+ * Hook for tracking phone and email contact interactions as conversions.
61
+ *
62
+ * @example
63
+ * ```tsx
64
+ * // Auto-track all tel: and mailto: links
65
+ * useContactTracking()
66
+ *
67
+ * // Manual tracking
68
+ * const { trackPhoneClick, trackEmailClick } = useContactTracking()
69
+ * trackPhoneClick('513-555-1234')
70
+ * trackEmailClick('hello@example.com')
71
+ * ```
72
+ */
73
+ declare function useContactTracking(options?: UseContactTrackingOptions): ContactTrackingReturn;
74
+ /**
75
+ * Component wrapper for contact tracking
76
+ * Simply include this component to auto-track all tel: and mailto: links
77
+ *
78
+ * @example
79
+ * ```tsx
80
+ * <ContactTracking />
81
+ * ```
82
+ */
83
+ declare function ContactTracking({ debug }: {
84
+ debug?: boolean;
85
+ }): null;
86
+
87
+ export { AnalyticsContextValue, AnalyticsProvider, ContactTracking, TrackConversionOptions, TrackEventOptions, WebVitals, useAnalytics, useContactTracking, useTrackEvent };
@@ -0,0 +1,87 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React__default from 'react';
3
+ import { A as AnalyticsContextValue, T as TrackEventOptions, a as TrackConversionOptions } from '../types-DA_Kocle.js';
4
+ export { c as AnalyticsConfig, b as AnalyticsEvent, C as Conversion, P as PageView, S as Session, W as WebVitalsData } from '../types-DA_Kocle.js';
5
+
6
+ interface AnalyticsProviderProps {
7
+ children: React__default.ReactNode;
8
+ apiUrl?: string;
9
+ apiKey?: string;
10
+ trackPageViews?: boolean;
11
+ trackWebVitals?: boolean;
12
+ trackScrollDepth?: boolean;
13
+ trackClicks?: boolean;
14
+ trackJourneys?: boolean;
15
+ sessionTimeout?: number;
16
+ excludePaths?: string[];
17
+ validateAgainstSitemap?: boolean;
18
+ debug?: boolean;
19
+ }
20
+ declare function AnalyticsProvider({ children, apiUrl: propApiUrl, apiKey: propApiKey, trackPageViews, trackWebVitals, trackScrollDepth, trackClicks, trackJourneys, // NEW: Enable journey tracking by default
21
+ sessionTimeout, excludePaths, validateAgainstSitemap, debug, }: AnalyticsProviderProps): react_jsx_runtime.JSX.Element;
22
+ declare function useAnalytics(): AnalyticsContextValue;
23
+ declare function useTrackEvent(): {
24
+ trackEvent: (options: TrackEventOptions) => void;
25
+ trackConversion: (options: TrackConversionOptions) => void;
26
+ };
27
+
28
+ /**
29
+ * @uptrade/site-kit/analytics - Web Vitals Component
30
+ *
31
+ * Automatically reports Core Web Vitals via Portal API
32
+ */
33
+ interface WebVitalsProps {
34
+ apiUrl?: string;
35
+ apiKey?: string;
36
+ debug?: boolean;
37
+ }
38
+ declare function WebVitals({ apiUrl: propApiUrl, apiKey: propApiKey, debug }: WebVitalsProps): null;
39
+
40
+ /**
41
+ * @uptrade/site-kit/analytics - Contact Tracking Hook
42
+ *
43
+ * Tracks phone calls and email clicks as conversions.
44
+ * Use this hook to automatically track tel: and mailto: links,
45
+ * or manually track contact interactions.
46
+ */
47
+ interface UseContactTrackingOptions {
48
+ /** Automatically track all tel: and mailto: links (default: true) */
49
+ autoTrack?: boolean;
50
+ /** Debug mode - logs events to console */
51
+ debug?: boolean;
52
+ }
53
+ interface ContactTrackingReturn {
54
+ /** Manually track a phone call click */
55
+ trackPhoneClick: (phoneNumber: string, metadata?: Record<string, unknown>) => void;
56
+ /** Manually track an email click */
57
+ trackEmailClick: (email: string, metadata?: Record<string, unknown>) => void;
58
+ }
59
+ /**
60
+ * Hook for tracking phone and email contact interactions as conversions.
61
+ *
62
+ * @example
63
+ * ```tsx
64
+ * // Auto-track all tel: and mailto: links
65
+ * useContactTracking()
66
+ *
67
+ * // Manual tracking
68
+ * const { trackPhoneClick, trackEmailClick } = useContactTracking()
69
+ * trackPhoneClick('513-555-1234')
70
+ * trackEmailClick('hello@example.com')
71
+ * ```
72
+ */
73
+ declare function useContactTracking(options?: UseContactTrackingOptions): ContactTrackingReturn;
74
+ /**
75
+ * Component wrapper for contact tracking
76
+ * Simply include this component to auto-track all tel: and mailto: links
77
+ *
78
+ * @example
79
+ * ```tsx
80
+ * <ContactTracking />
81
+ * ```
82
+ */
83
+ declare function ContactTracking({ debug }: {
84
+ debug?: boolean;
85
+ }): null;
86
+
87
+ export { AnalyticsContextValue, AnalyticsProvider, ContactTracking, TrackConversionOptions, TrackEventOptions, WebVitals, useAnalytics, useContactTracking, useTrackEvent };
@@ -0,0 +1,24 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { B as BlogPostProps, a as BlogListProps, A as AuthorCardProps, b as BlogPost$1, T as TableOfContentsProps } from '../types-BDojCvvL.mjs';
3
+ export { k as BlogAnalytics, c as BlogAuthor, d as BlogCategory, f as BlogListOptions, i as BlogListRenderProps, g as BlogListResult, h as BlogPostRenderProps, e as BlogTag, R as RelatedPostsProps, j as TocItem } from '../types-BDojCvvL.mjs';
4
+ import React__default from 'react';
5
+
6
+ declare function BlogPost({ projectId, slug, children }: BlogPostProps): Promise<react_jsx_runtime.JSX.Element>;
7
+
8
+ declare function BlogList({ projectId, options, children }: BlogListProps): Promise<react_jsx_runtime.JSX.Element>;
9
+
10
+ declare function AuthorCard({ author, showBio, showSocial, className }: AuthorCardProps): react_jsx_runtime.JSX.Element;
11
+
12
+ interface RelatedPostsServerProps {
13
+ apiUrl?: string;
14
+ apiKey?: string;
15
+ currentPostId: string;
16
+ limit?: number;
17
+ className?: string;
18
+ renderItem?: (post: BlogPost$1) => React__default.ReactNode;
19
+ }
20
+ declare function RelatedPosts({ apiUrl, apiKey, currentPostId, limit, className, renderItem, }: RelatedPostsServerProps): Promise<react_jsx_runtime.JSX.Element | null>;
21
+
22
+ declare function TableOfContents({ content, className, maxDepth, }: TableOfContentsProps): react_jsx_runtime.JSX.Element | null;
23
+
24
+ export { AuthorCard, AuthorCardProps, BlogList, BlogListProps, BlogPost, BlogPostProps, RelatedPosts, TableOfContents, TableOfContentsProps };
@@ -0,0 +1,24 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { B as BlogPostProps, a as BlogListProps, A as AuthorCardProps, b as BlogPost$1, T as TableOfContentsProps } from '../types-BDojCvvL.js';
3
+ export { k as BlogAnalytics, c as BlogAuthor, d as BlogCategory, f as BlogListOptions, i as BlogListRenderProps, g as BlogListResult, h as BlogPostRenderProps, e as BlogTag, R as RelatedPostsProps, j as TocItem } from '../types-BDojCvvL.js';
4
+ import React__default from 'react';
5
+
6
+ declare function BlogPost({ projectId, slug, children }: BlogPostProps): Promise<react_jsx_runtime.JSX.Element>;
7
+
8
+ declare function BlogList({ projectId, options, children }: BlogListProps): Promise<react_jsx_runtime.JSX.Element>;
9
+
10
+ declare function AuthorCard({ author, showBio, showSocial, className }: AuthorCardProps): react_jsx_runtime.JSX.Element;
11
+
12
+ interface RelatedPostsServerProps {
13
+ apiUrl?: string;
14
+ apiKey?: string;
15
+ currentPostId: string;
16
+ limit?: number;
17
+ className?: string;
18
+ renderItem?: (post: BlogPost$1) => React__default.ReactNode;
19
+ }
20
+ declare function RelatedPosts({ apiUrl, apiKey, currentPostId, limit, className, renderItem, }: RelatedPostsServerProps): Promise<react_jsx_runtime.JSX.Element | null>;
21
+
22
+ declare function TableOfContents({ content, className, maxDepth, }: TableOfContentsProps): react_jsx_runtime.JSX.Element | null;
23
+
24
+ export { AuthorCard, AuthorCardProps, BlogList, BlogListProps, BlogPost, BlogPostProps, RelatedPosts, TableOfContents, TableOfContentsProps };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/blog/BlogPost.tsx","../../src/blog/BlogList.tsx","../../src/blog/AuthorCard.tsx","../../src/blog/RelatedPosts.tsx","../../src/blog/TableOfContents.tsx"],"names":["jsxs","jsx","useState","useEffect"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @uptrade/site-kit/blog - Blog Post Component (Placeholder)\n */\n\nimport React from 'react'\nimport type { BlogPostProps } from './types'\n\nexport async function BlogPost({ projectId, slug, children }: BlogPostProps) {\n // Placeholder - full implementation will:\n // 1. Fetch post from Supabase\n // 2. Parse content (markdown to HTML if needed)\n // 3. Generate table of contents\n // 4. Fetch related posts\n // 5. Track view analytics\n \n return (\n <div>\n <p>Blog post: {slug}</p>\n <p>Coming soon...</p>\n </div>\n )\n}\n","/**\n * @uptrade/site-kit/blog - Blog List Component (Placeholder)\n */\n\nimport React from 'react'\nimport type { BlogListProps } from './types'\n\nexport async function BlogList({ projectId, options, children }: BlogListProps) {\n // Placeholder - full implementation will:\n // 1. Fetch posts with pagination\n // 2. Apply filters (category, tag, search)\n // 3. Fetch categories and tags for filtering UI\n \n return (\n <div>\n <p>Blog list for project: {projectId}</p>\n <p>Coming soon...</p>\n </div>\n )\n}\n","/**\n * @uptrade/site-kit/blog - Author Card Component\n */\n\nimport React from 'react'\nimport type { AuthorCardProps } from './types'\n\nexport function AuthorCard({ author, showBio = true, showSocial = true, className }: AuthorCardProps) {\n return (\n <div className={className} style={{ display: 'flex', gap: 16, alignItems: 'flex-start' }}>\n {author.avatar_url && (\n <img\n src={author.avatar_url}\n alt={author.name}\n style={{\n width: 64,\n height: 64,\n borderRadius: '50%',\n objectFit: 'cover',\n }}\n />\n )}\n <div>\n <h4 style={{ margin: 0 }}>{author.name}</h4>\n {showBio && author.bio && (\n <p style={{ margin: '4px 0', color: '#6b7280', fontSize: 14 }}>{author.bio}</p>\n )}\n {showSocial && author.social_links && (\n <div style={{ display: 'flex', gap: 12, marginTop: 8 }}>\n {author.social_links.twitter && (\n <a href={`https://twitter.com/${author.social_links.twitter}`} target=\"_blank\" rel=\"noopener noreferrer\">\n Twitter\n </a>\n )}\n {author.social_links.linkedin && (\n <a href={author.social_links.linkedin} target=\"_blank\" rel=\"noopener noreferrer\">\n LinkedIn\n </a>\n )}\n {author.social_links.github && (\n <a href={`https://github.com/${author.social_links.github}`} target=\"_blank\" rel=\"noopener noreferrer\">\n GitHub\n </a>\n )}\n </div>\n )}\n </div>\n </div>\n )\n}\n","/**\n * @uptrade/site-kit/blog - Related Posts Component\n * \n * Fetches and displays related blog posts via Portal API\n */\n\nimport React from 'react'\nimport type { RelatedPostsProps, BlogPost } from './types'\n\nasync function fetchRelatedPosts(\n apiUrl: string,\n apiKey: string,\n currentPostId: string,\n limit: number\n): Promise<BlogPost[]> {\n try {\n const response = await fetch(`${apiUrl}/api/public/blog/related`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify({\n currentPostId,\n limit,\n }),\n })\n \n if (!response.ok) {\n console.error('Failed to fetch related posts:', response.statusText)\n return []\n }\n \n const data = await response.json()\n return data.posts || []\n } catch (error) {\n console.error('Failed to fetch related posts:', error)\n return []\n }\n}\n\ninterface RelatedPostsServerProps extends Omit<RelatedPostsProps, 'projectId'> {\n apiUrl?: string\n apiKey?: string\n}\n\nexport async function RelatedPosts({\n apiUrl = process.env.NEXT_PUBLIC_UPTRADE_API_URL || 'https://api.uptrademedia.com',\n apiKey = process.env.NEXT_PUBLIC_UPTRADE_API_KEY || '',\n currentPostId,\n limit = 3,\n className,\n renderItem,\n}: RelatedPostsServerProps) {\n if (!apiKey) {\n console.warn('[Blog] No API key configured for RelatedPosts')\n return null\n }\n \n const posts = await fetchRelatedPosts(apiUrl, apiKey, currentPostId, limit)\n\n if (posts.length === 0) return null\n\n return (\n <section className={className}>\n <h3 style={{ marginBottom: 16 }}>Related Posts</h3>\n <div style={{ display: 'grid', gap: 16 }}>\n {posts.map((post) =>\n renderItem ? (\n renderItem(post)\n ) : (\n <article key={post.id} style={{ borderBottom: '1px solid #e5e7eb', paddingBottom: 16 }}>\n {post.featured_image && (\n <img\n src={post.featured_image}\n alt={post.title}\n style={{\n width: '100%',\n height: 120,\n objectFit: 'cover',\n borderRadius: 8,\n marginBottom: 8,\n }}\n />\n )}\n <a href={`/blog/${post.slug}`} style={{ textDecoration: 'none' }}>\n <h4 style={{ margin: 0, color: 'inherit' }}>{post.title}</h4>\n </a>\n {post.excerpt && (\n <p style={{ margin: '4px 0 0', fontSize: 14, color: '#6b7280' }}>\n {post.excerpt}\n </p>\n )}\n </article>\n )\n )}\n </div>\n </section>\n )\n}\n","/**\n * @uptrade/site-kit/blog - Table of Contents Component\n */\n\n'use client'\n\nimport React, { useState, useEffect } from 'react'\nimport type { TableOfContentsProps } from './types'\n\ninterface TocItem {\n id: string\n text: string\n level: number\n}\n\nfunction parseHeadings(content: string): TocItem[] {\n // Extract headings from HTML content\n const headingRegex = /<h([2-4])[^>]*id=\"([^\"]*)\"[^>]*>(.*?)<\\/h[2-4]>/gi\n const items: TocItem[] = []\n let match\n\n while ((match = headingRegex.exec(content)) !== null) {\n items.push({\n level: parseInt(match[1]),\n id: match[2],\n text: match[3].replace(/<[^>]*>/g, ''), // Strip any nested HTML\n })\n }\n\n return items\n}\n\nexport function TableOfContents({\n content,\n className,\n maxDepth = 3,\n}: TableOfContentsProps) {\n const [activeId, setActiveId] = useState<string>('')\n const items = parseHeadings(content).filter((item) => item.level <= maxDepth)\n\n useEffect(() => {\n if (typeof window === 'undefined') return\n\n const observer = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (entry.isIntersecting) {\n setActiveId(entry.target.id)\n }\n })\n },\n {\n rootMargin: '-20% 0% -35% 0%',\n threshold: 0,\n }\n )\n\n // Observe all headings\n items.forEach((item) => {\n const element = document.getElementById(item.id)\n if (element) {\n observer.observe(element)\n }\n })\n\n return () => observer.disconnect()\n }, [items])\n\n if (items.length === 0) return null\n\n const handleClick = (id: string) => {\n const element = document.getElementById(id)\n if (element) {\n element.scrollIntoView({ behavior: 'smooth' })\n }\n }\n\n return (\n <nav className={className} aria-label=\"Table of contents\">\n <h4 style={{ margin: '0 0 12px', fontSize: 14, fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.05em' }}>\n On This Page\n </h4>\n <ul style={{ listStyle: 'none', margin: 0, padding: 0 }}>\n {items.map((item) => (\n <li\n key={item.id}\n style={{\n paddingLeft: (item.level - 2) * 12,\n marginBottom: 8,\n }}\n >\n <button\n onClick={() => handleClick(item.id)}\n style={{\n all: 'unset',\n cursor: 'pointer',\n fontSize: 14,\n color: activeId === item.id ? '#2563eb' : '#6b7280',\n fontWeight: activeId === item.id ? 500 : 400,\n transition: 'color 0.2s',\n }}\n >\n {item.text}\n </button>\n </li>\n ))}\n </ul>\n </nav>\n )\n}\n"]}
1
+ {"version":3,"sources":["../../src/blog/BlogPost.tsx","../../src/blog/BlogList.tsx","../../src/blog/AuthorCard.tsx","../../src/blog/RelatedPosts.tsx","../../src/blog/TableOfContents.tsx"],"names":["jsxs","jsx","useState","useEffect"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @uptrade/site-kit/blog - Blog Post Component (Placeholder)\n */\n\nimport React from 'react'\nimport type { BlogPostProps } from './types'\n\nexport async function BlogPost({ projectId, slug, children }: BlogPostProps) {\n // Placeholder - full implementation will:\n // 1. Fetch post from Supabase\n // 2. Parse content (markdown to HTML if needed)\n // 3. Generate table of contents\n // 4. Fetch related posts\n // 5. Track view analytics\n \n return (\n <div>\n <p>Blog post: {slug}</p>\n <p>Coming soon...</p>\n </div>\n )\n}\n","/**\n * @uptrade/site-kit/blog - Blog List Component (Placeholder)\n */\n\nimport React from 'react'\nimport type { BlogListProps } from './types'\n\nexport async function BlogList({ projectId, options, children }: BlogListProps) {\n // Placeholder - full implementation will:\n // 1. Fetch posts with pagination\n // 2. Apply filters (category, tag, search)\n // 3. Fetch categories and tags for filtering UI\n \n return (\n <div>\n <p>Blog list for project: {projectId}</p>\n <p>Coming soon...</p>\n </div>\n )\n}\n","/**\n * @uptrade/site-kit/blog - Author Card Component\n */\n\nimport React from 'react'\nimport type { AuthorCardProps } from './types'\n\nexport function AuthorCard({ author, showBio = true, showSocial = true, className }: AuthorCardProps) {\n return (\n <div className={className} style={{ display: 'flex', gap: 16, alignItems: 'flex-start' }}>\n {author.avatar_url && (\n <img\n src={author.avatar_url}\n alt={author.name}\n style={{\n width: 64,\n height: 64,\n borderRadius: '50%',\n objectFit: 'cover',\n }}\n />\n )}\n <div>\n <h4 style={{ margin: 0 }}>{author.name}</h4>\n {showBio && author.bio && (\n <p style={{ margin: '4px 0', color: '#6b7280', fontSize: 14 }}>{author.bio}</p>\n )}\n {showSocial && author.social_links && (\n <div style={{ display: 'flex', gap: 12, marginTop: 8 }}>\n {author.social_links.twitter && (\n <a href={`https://twitter.com/${author.social_links.twitter}`} target=\"_blank\" rel=\"noopener noreferrer\">\n Twitter\n </a>\n )}\n {author.social_links.linkedin && (\n <a href={author.social_links.linkedin} target=\"_blank\" rel=\"noopener noreferrer\">\n LinkedIn\n </a>\n )}\n {author.social_links.github && (\n <a href={`https://github.com/${author.social_links.github}`} target=\"_blank\" rel=\"noopener noreferrer\">\n GitHub\n </a>\n )}\n </div>\n )}\n </div>\n </div>\n )\n}\n","/**\n * @uptrade/site-kit/blog - Related Posts Component\n * \n * Fetches and displays related blog posts via Portal API\n */\n\nimport React from 'react'\nimport type { RelatedPostsProps, BlogPost } from './types'\n\nasync function fetchRelatedPosts(\n apiUrl: string,\n apiKey: string,\n currentPostId: string,\n limit: number\n): Promise<BlogPost[]> {\n try {\n const response = await fetch(`${apiUrl}/api/public/blog/related`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify({\n currentPostId,\n limit,\n }),\n })\n \n if (!response.ok) {\n console.error('Failed to fetch related posts:', response.statusText)\n return []\n }\n \n const data = await response.json()\n return data.posts || []\n } catch (error) {\n console.error('Failed to fetch related posts:', error)\n return []\n }\n}\n\ninterface RelatedPostsServerProps {\n apiUrl?: string\n apiKey?: string\n currentPostId: string\n limit?: number\n className?: string\n renderItem?: (post: BlogPost) => React.ReactNode\n}\n\nexport async function RelatedPosts({\n apiUrl = process.env.NEXT_PUBLIC_UPTRADE_API_URL || 'https://api.uptrademedia.com',\n apiKey = process.env.NEXT_PUBLIC_UPTRADE_API_KEY || '',\n currentPostId,\n limit = 3,\n className,\n renderItem,\n}: RelatedPostsServerProps) {\n if (!apiKey) {\n console.warn('[Blog] No API key configured for RelatedPosts')\n return null\n }\n \n const posts = await fetchRelatedPosts(apiUrl, apiKey, currentPostId, limit)\n\n if (posts.length === 0) return null\n\n return (\n <section className={className}>\n <h3 style={{ marginBottom: 16 }}>Related Posts</h3>\n <div style={{ display: 'grid', gap: 16 }}>\n {posts.map((post) =>\n renderItem ? (\n renderItem(post)\n ) : (\n <article key={post.id} style={{ borderBottom: '1px solid #e5e7eb', paddingBottom: 16 }}>\n {post.featured_image && (\n <img\n src={post.featured_image}\n alt={post.title}\n style={{\n width: '100%',\n height: 120,\n objectFit: 'cover',\n borderRadius: 8,\n marginBottom: 8,\n }}\n />\n )}\n <a href={`/blog/${post.slug}`} style={{ textDecoration: 'none' }}>\n <h4 style={{ margin: 0, color: 'inherit' }}>{post.title}</h4>\n </a>\n {post.excerpt && (\n <p style={{ margin: '4px 0 0', fontSize: 14, color: '#6b7280' }}>\n {post.excerpt}\n </p>\n )}\n </article>\n )\n )}\n </div>\n </section>\n )\n}\n","/**\n * @uptrade/site-kit/blog - Table of Contents Component\n */\n\n'use client'\n\nimport React, { useState, useEffect } from 'react'\nimport type { TableOfContentsProps } from './types'\n\ninterface TocItem {\n id: string\n text: string\n level: number\n}\n\nfunction parseHeadings(content: string): TocItem[] {\n // Extract headings from HTML content\n const headingRegex = /<h([2-4])[^>]*id=\"([^\"]*)\"[^>]*>(.*?)<\\/h[2-4]>/gi\n const items: TocItem[] = []\n let match\n\n while ((match = headingRegex.exec(content)) !== null) {\n items.push({\n level: parseInt(match[1]),\n id: match[2],\n text: match[3].replace(/<[^>]*>/g, ''), // Strip any nested HTML\n })\n }\n\n return items\n}\n\nexport function TableOfContents({\n content,\n className,\n maxDepth = 3,\n}: TableOfContentsProps) {\n const [activeId, setActiveId] = useState<string>('')\n const items = parseHeadings(content).filter((item) => item.level <= maxDepth)\n\n useEffect(() => {\n if (typeof window === 'undefined') return\n\n const observer = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (entry.isIntersecting) {\n setActiveId(entry.target.id)\n }\n })\n },\n {\n rootMargin: '-20% 0% -35% 0%',\n threshold: 0,\n }\n )\n\n // Observe all headings\n items.forEach((item) => {\n const element = document.getElementById(item.id)\n if (element) {\n observer.observe(element)\n }\n })\n\n return () => observer.disconnect()\n }, [items])\n\n if (items.length === 0) return null\n\n const handleClick = (id: string) => {\n const element = document.getElementById(id)\n if (element) {\n element.scrollIntoView({ behavior: 'smooth' })\n }\n }\n\n return (\n <nav className={className} aria-label=\"Table of contents\">\n <h4 style={{ margin: '0 0 12px', fontSize: 14, fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.05em' }}>\n On This Page\n </h4>\n <ul style={{ listStyle: 'none', margin: 0, padding: 0 }}>\n {items.map((item) => (\n <li\n key={item.id}\n style={{\n paddingLeft: (item.level - 2) * 12,\n marginBottom: 8,\n }}\n >\n <button\n onClick={() => handleClick(item.id)}\n style={{\n all: 'unset',\n cursor: 'pointer',\n fontSize: 14,\n color: activeId === item.id ? '#2563eb' : '#6b7280',\n fontWeight: activeId === item.id ? 500 : 400,\n transition: 'color 0.2s',\n }}\n >\n {item.text}\n </button>\n </li>\n ))}\n </ul>\n </nav>\n )\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/blog/BlogPost.tsx","../../src/blog/BlogList.tsx","../../src/blog/AuthorCard.tsx","../../src/blog/RelatedPosts.tsx","../../src/blog/TableOfContents.tsx"],"names":["jsxs","jsx"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * @uptrade/site-kit/blog - Blog Post Component (Placeholder)\n */\n\nimport React from 'react'\nimport type { BlogPostProps } from './types'\n\nexport async function BlogPost({ projectId, slug, children }: BlogPostProps) {\n // Placeholder - full implementation will:\n // 1. Fetch post from Supabase\n // 2. Parse content (markdown to HTML if needed)\n // 3. Generate table of contents\n // 4. Fetch related posts\n // 5. Track view analytics\n \n return (\n <div>\n <p>Blog post: {slug}</p>\n <p>Coming soon...</p>\n </div>\n )\n}\n","/**\n * @uptrade/site-kit/blog - Blog List Component (Placeholder)\n */\n\nimport React from 'react'\nimport type { BlogListProps } from './types'\n\nexport async function BlogList({ projectId, options, children }: BlogListProps) {\n // Placeholder - full implementation will:\n // 1. Fetch posts with pagination\n // 2. Apply filters (category, tag, search)\n // 3. Fetch categories and tags for filtering UI\n \n return (\n <div>\n <p>Blog list for project: {projectId}</p>\n <p>Coming soon...</p>\n </div>\n )\n}\n","/**\n * @uptrade/site-kit/blog - Author Card Component\n */\n\nimport React from 'react'\nimport type { AuthorCardProps } from './types'\n\nexport function AuthorCard({ author, showBio = true, showSocial = true, className }: AuthorCardProps) {\n return (\n <div className={className} style={{ display: 'flex', gap: 16, alignItems: 'flex-start' }}>\n {author.avatar_url && (\n <img\n src={author.avatar_url}\n alt={author.name}\n style={{\n width: 64,\n height: 64,\n borderRadius: '50%',\n objectFit: 'cover',\n }}\n />\n )}\n <div>\n <h4 style={{ margin: 0 }}>{author.name}</h4>\n {showBio && author.bio && (\n <p style={{ margin: '4px 0', color: '#6b7280', fontSize: 14 }}>{author.bio}</p>\n )}\n {showSocial && author.social_links && (\n <div style={{ display: 'flex', gap: 12, marginTop: 8 }}>\n {author.social_links.twitter && (\n <a href={`https://twitter.com/${author.social_links.twitter}`} target=\"_blank\" rel=\"noopener noreferrer\">\n Twitter\n </a>\n )}\n {author.social_links.linkedin && (\n <a href={author.social_links.linkedin} target=\"_blank\" rel=\"noopener noreferrer\">\n LinkedIn\n </a>\n )}\n {author.social_links.github && (\n <a href={`https://github.com/${author.social_links.github}`} target=\"_blank\" rel=\"noopener noreferrer\">\n GitHub\n </a>\n )}\n </div>\n )}\n </div>\n </div>\n )\n}\n","/**\n * @uptrade/site-kit/blog - Related Posts Component\n * \n * Fetches and displays related blog posts via Portal API\n */\n\nimport React from 'react'\nimport type { RelatedPostsProps, BlogPost } from './types'\n\nasync function fetchRelatedPosts(\n apiUrl: string,\n apiKey: string,\n currentPostId: string,\n limit: number\n): Promise<BlogPost[]> {\n try {\n const response = await fetch(`${apiUrl}/api/public/blog/related`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify({\n currentPostId,\n limit,\n }),\n })\n \n if (!response.ok) {\n console.error('Failed to fetch related posts:', response.statusText)\n return []\n }\n \n const data = await response.json()\n return data.posts || []\n } catch (error) {\n console.error('Failed to fetch related posts:', error)\n return []\n }\n}\n\ninterface RelatedPostsServerProps extends Omit<RelatedPostsProps, 'projectId'> {\n apiUrl?: string\n apiKey?: string\n}\n\nexport async function RelatedPosts({\n apiUrl = process.env.NEXT_PUBLIC_UPTRADE_API_URL || 'https://api.uptrademedia.com',\n apiKey = process.env.NEXT_PUBLIC_UPTRADE_API_KEY || '',\n currentPostId,\n limit = 3,\n className,\n renderItem,\n}: RelatedPostsServerProps) {\n if (!apiKey) {\n console.warn('[Blog] No API key configured for RelatedPosts')\n return null\n }\n \n const posts = await fetchRelatedPosts(apiUrl, apiKey, currentPostId, limit)\n\n if (posts.length === 0) return null\n\n return (\n <section className={className}>\n <h3 style={{ marginBottom: 16 }}>Related Posts</h3>\n <div style={{ display: 'grid', gap: 16 }}>\n {posts.map((post) =>\n renderItem ? (\n renderItem(post)\n ) : (\n <article key={post.id} style={{ borderBottom: '1px solid #e5e7eb', paddingBottom: 16 }}>\n {post.featured_image && (\n <img\n src={post.featured_image}\n alt={post.title}\n style={{\n width: '100%',\n height: 120,\n objectFit: 'cover',\n borderRadius: 8,\n marginBottom: 8,\n }}\n />\n )}\n <a href={`/blog/${post.slug}`} style={{ textDecoration: 'none' }}>\n <h4 style={{ margin: 0, color: 'inherit' }}>{post.title}</h4>\n </a>\n {post.excerpt && (\n <p style={{ margin: '4px 0 0', fontSize: 14, color: '#6b7280' }}>\n {post.excerpt}\n </p>\n )}\n </article>\n )\n )}\n </div>\n </section>\n )\n}\n","/**\n * @uptrade/site-kit/blog - Table of Contents Component\n */\n\n'use client'\n\nimport React, { useState, useEffect } from 'react'\nimport type { TableOfContentsProps } from './types'\n\ninterface TocItem {\n id: string\n text: string\n level: number\n}\n\nfunction parseHeadings(content: string): TocItem[] {\n // Extract headings from HTML content\n const headingRegex = /<h([2-4])[^>]*id=\"([^\"]*)\"[^>]*>(.*?)<\\/h[2-4]>/gi\n const items: TocItem[] = []\n let match\n\n while ((match = headingRegex.exec(content)) !== null) {\n items.push({\n level: parseInt(match[1]),\n id: match[2],\n text: match[3].replace(/<[^>]*>/g, ''), // Strip any nested HTML\n })\n }\n\n return items\n}\n\nexport function TableOfContents({\n content,\n className,\n maxDepth = 3,\n}: TableOfContentsProps) {\n const [activeId, setActiveId] = useState<string>('')\n const items = parseHeadings(content).filter((item) => item.level <= maxDepth)\n\n useEffect(() => {\n if (typeof window === 'undefined') return\n\n const observer = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (entry.isIntersecting) {\n setActiveId(entry.target.id)\n }\n })\n },\n {\n rootMargin: '-20% 0% -35% 0%',\n threshold: 0,\n }\n )\n\n // Observe all headings\n items.forEach((item) => {\n const element = document.getElementById(item.id)\n if (element) {\n observer.observe(element)\n }\n })\n\n return () => observer.disconnect()\n }, [items])\n\n if (items.length === 0) return null\n\n const handleClick = (id: string) => {\n const element = document.getElementById(id)\n if (element) {\n element.scrollIntoView({ behavior: 'smooth' })\n }\n }\n\n return (\n <nav className={className} aria-label=\"Table of contents\">\n <h4 style={{ margin: '0 0 12px', fontSize: 14, fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.05em' }}>\n On This Page\n </h4>\n <ul style={{ listStyle: 'none', margin: 0, padding: 0 }}>\n {items.map((item) => (\n <li\n key={item.id}\n style={{\n paddingLeft: (item.level - 2) * 12,\n marginBottom: 8,\n }}\n >\n <button\n onClick={() => handleClick(item.id)}\n style={{\n all: 'unset',\n cursor: 'pointer',\n fontSize: 14,\n color: activeId === item.id ? '#2563eb' : '#6b7280',\n fontWeight: activeId === item.id ? 500 : 400,\n transition: 'color 0.2s',\n }}\n >\n {item.text}\n </button>\n </li>\n ))}\n </ul>\n </nav>\n )\n}\n"]}
1
+ {"version":3,"sources":["../../src/blog/BlogPost.tsx","../../src/blog/BlogList.tsx","../../src/blog/AuthorCard.tsx","../../src/blog/RelatedPosts.tsx","../../src/blog/TableOfContents.tsx"],"names":["jsxs","jsx"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * @uptrade/site-kit/blog - Blog Post Component (Placeholder)\n */\n\nimport React from 'react'\nimport type { BlogPostProps } from './types'\n\nexport async function BlogPost({ projectId, slug, children }: BlogPostProps) {\n // Placeholder - full implementation will:\n // 1. Fetch post from Supabase\n // 2. Parse content (markdown to HTML if needed)\n // 3. Generate table of contents\n // 4. Fetch related posts\n // 5. Track view analytics\n \n return (\n <div>\n <p>Blog post: {slug}</p>\n <p>Coming soon...</p>\n </div>\n )\n}\n","/**\n * @uptrade/site-kit/blog - Blog List Component (Placeholder)\n */\n\nimport React from 'react'\nimport type { BlogListProps } from './types'\n\nexport async function BlogList({ projectId, options, children }: BlogListProps) {\n // Placeholder - full implementation will:\n // 1. Fetch posts with pagination\n // 2. Apply filters (category, tag, search)\n // 3. Fetch categories and tags for filtering UI\n \n return (\n <div>\n <p>Blog list for project: {projectId}</p>\n <p>Coming soon...</p>\n </div>\n )\n}\n","/**\n * @uptrade/site-kit/blog - Author Card Component\n */\n\nimport React from 'react'\nimport type { AuthorCardProps } from './types'\n\nexport function AuthorCard({ author, showBio = true, showSocial = true, className }: AuthorCardProps) {\n return (\n <div className={className} style={{ display: 'flex', gap: 16, alignItems: 'flex-start' }}>\n {author.avatar_url && (\n <img\n src={author.avatar_url}\n alt={author.name}\n style={{\n width: 64,\n height: 64,\n borderRadius: '50%',\n objectFit: 'cover',\n }}\n />\n )}\n <div>\n <h4 style={{ margin: 0 }}>{author.name}</h4>\n {showBio && author.bio && (\n <p style={{ margin: '4px 0', color: '#6b7280', fontSize: 14 }}>{author.bio}</p>\n )}\n {showSocial && author.social_links && (\n <div style={{ display: 'flex', gap: 12, marginTop: 8 }}>\n {author.social_links.twitter && (\n <a href={`https://twitter.com/${author.social_links.twitter}`} target=\"_blank\" rel=\"noopener noreferrer\">\n Twitter\n </a>\n )}\n {author.social_links.linkedin && (\n <a href={author.social_links.linkedin} target=\"_blank\" rel=\"noopener noreferrer\">\n LinkedIn\n </a>\n )}\n {author.social_links.github && (\n <a href={`https://github.com/${author.social_links.github}`} target=\"_blank\" rel=\"noopener noreferrer\">\n GitHub\n </a>\n )}\n </div>\n )}\n </div>\n </div>\n )\n}\n","/**\n * @uptrade/site-kit/blog - Related Posts Component\n * \n * Fetches and displays related blog posts via Portal API\n */\n\nimport React from 'react'\nimport type { RelatedPostsProps, BlogPost } from './types'\n\nasync function fetchRelatedPosts(\n apiUrl: string,\n apiKey: string,\n currentPostId: string,\n limit: number\n): Promise<BlogPost[]> {\n try {\n const response = await fetch(`${apiUrl}/api/public/blog/related`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify({\n currentPostId,\n limit,\n }),\n })\n \n if (!response.ok) {\n console.error('Failed to fetch related posts:', response.statusText)\n return []\n }\n \n const data = await response.json()\n return data.posts || []\n } catch (error) {\n console.error('Failed to fetch related posts:', error)\n return []\n }\n}\n\ninterface RelatedPostsServerProps {\n apiUrl?: string\n apiKey?: string\n currentPostId: string\n limit?: number\n className?: string\n renderItem?: (post: BlogPost) => React.ReactNode\n}\n\nexport async function RelatedPosts({\n apiUrl = process.env.NEXT_PUBLIC_UPTRADE_API_URL || 'https://api.uptrademedia.com',\n apiKey = process.env.NEXT_PUBLIC_UPTRADE_API_KEY || '',\n currentPostId,\n limit = 3,\n className,\n renderItem,\n}: RelatedPostsServerProps) {\n if (!apiKey) {\n console.warn('[Blog] No API key configured for RelatedPosts')\n return null\n }\n \n const posts = await fetchRelatedPosts(apiUrl, apiKey, currentPostId, limit)\n\n if (posts.length === 0) return null\n\n return (\n <section className={className}>\n <h3 style={{ marginBottom: 16 }}>Related Posts</h3>\n <div style={{ display: 'grid', gap: 16 }}>\n {posts.map((post) =>\n renderItem ? (\n renderItem(post)\n ) : (\n <article key={post.id} style={{ borderBottom: '1px solid #e5e7eb', paddingBottom: 16 }}>\n {post.featured_image && (\n <img\n src={post.featured_image}\n alt={post.title}\n style={{\n width: '100%',\n height: 120,\n objectFit: 'cover',\n borderRadius: 8,\n marginBottom: 8,\n }}\n />\n )}\n <a href={`/blog/${post.slug}`} style={{ textDecoration: 'none' }}>\n <h4 style={{ margin: 0, color: 'inherit' }}>{post.title}</h4>\n </a>\n {post.excerpt && (\n <p style={{ margin: '4px 0 0', fontSize: 14, color: '#6b7280' }}>\n {post.excerpt}\n </p>\n )}\n </article>\n )\n )}\n </div>\n </section>\n )\n}\n","/**\n * @uptrade/site-kit/blog - Table of Contents Component\n */\n\n'use client'\n\nimport React, { useState, useEffect } from 'react'\nimport type { TableOfContentsProps } from './types'\n\ninterface TocItem {\n id: string\n text: string\n level: number\n}\n\nfunction parseHeadings(content: string): TocItem[] {\n // Extract headings from HTML content\n const headingRegex = /<h([2-4])[^>]*id=\"([^\"]*)\"[^>]*>(.*?)<\\/h[2-4]>/gi\n const items: TocItem[] = []\n let match\n\n while ((match = headingRegex.exec(content)) !== null) {\n items.push({\n level: parseInt(match[1]),\n id: match[2],\n text: match[3].replace(/<[^>]*>/g, ''), // Strip any nested HTML\n })\n }\n\n return items\n}\n\nexport function TableOfContents({\n content,\n className,\n maxDepth = 3,\n}: TableOfContentsProps) {\n const [activeId, setActiveId] = useState<string>('')\n const items = parseHeadings(content).filter((item) => item.level <= maxDepth)\n\n useEffect(() => {\n if (typeof window === 'undefined') return\n\n const observer = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (entry.isIntersecting) {\n setActiveId(entry.target.id)\n }\n })\n },\n {\n rootMargin: '-20% 0% -35% 0%',\n threshold: 0,\n }\n )\n\n // Observe all headings\n items.forEach((item) => {\n const element = document.getElementById(item.id)\n if (element) {\n observer.observe(element)\n }\n })\n\n return () => observer.disconnect()\n }, [items])\n\n if (items.length === 0) return null\n\n const handleClick = (id: string) => {\n const element = document.getElementById(id)\n if (element) {\n element.scrollIntoView({ behavior: 'smooth' })\n }\n }\n\n return (\n <nav className={className} aria-label=\"Table of contents\">\n <h4 style={{ margin: '0 0 12px', fontSize: 14, fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.05em' }}>\n On This Page\n </h4>\n <ul style={{ listStyle: 'none', margin: 0, padding: 0 }}>\n {items.map((item) => (\n <li\n key={item.id}\n style={{\n paddingLeft: (item.level - 2) * 12,\n marginBottom: 8,\n }}\n >\n <button\n onClick={() => handleClick(item.id)}\n style={{\n all: 'unset',\n cursor: 'pointer',\n fontSize: 14,\n color: activeId === item.id ? '#2563eb' : '#6b7280',\n fontWeight: activeId === item.id ? 500 : 400,\n transition: 'color 0.2s',\n }}\n >\n {item.text}\n </button>\n </li>\n ))}\n </ul>\n </nav>\n )\n}\n"]}