@uptrademedia/site-kit 1.0.4 → 1.0.7

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 (178) hide show
  1. package/README.md +96 -25
  2. package/dist/analytics/index.js +7 -7
  3. package/dist/analytics/index.mjs +3 -3
  4. package/dist/api-QUIPJJCX.js +77 -0
  5. package/dist/api-QUIPJJCX.js.map +1 -0
  6. package/dist/api-V3BA5PMX.mjs +4 -0
  7. package/dist/api-V3BA5PMX.mjs.map +1 -0
  8. package/dist/blog/index.d.mts +160 -5
  9. package/dist/blog/index.d.ts +160 -5
  10. package/dist/blog/index.js +1166 -18
  11. package/dist/blog/index.js.map +1 -1
  12. package/dist/blog/index.mjs +1156 -18
  13. package/dist/blog/index.mjs.map +1 -1
  14. package/dist/blog/server.d.mts +229 -0
  15. package/dist/blog/server.d.ts +229 -0
  16. package/dist/blog/server.js +692 -0
  17. package/dist/blog/server.js.map +1 -0
  18. package/dist/blog/server.mjs +666 -0
  19. package/dist/blog/server.mjs.map +1 -0
  20. package/dist/{chunk-FKVJOT2F.mjs → chunk-42EXHJTC.mjs} +196 -7
  21. package/dist/chunk-42EXHJTC.mjs.map +1 -0
  22. package/dist/{scanner-AZV5I6US.mjs → chunk-44OMJFCG.mjs} +354 -14
  23. package/dist/chunk-44OMJFCG.mjs.map +1 -0
  24. package/dist/chunk-4TGJYNHV.js +981 -0
  25. package/dist/chunk-4TGJYNHV.js.map +1 -0
  26. package/dist/chunk-4XPGGLVP.mjs +53 -0
  27. package/dist/{chunk-NYKRE2FL.mjs.map → chunk-4XPGGLVP.mjs.map} +1 -1
  28. package/dist/{generators-TO2FKJR6.mjs → chunk-6ONUXZDO.mjs} +26 -9
  29. package/dist/chunk-6ONUXZDO.mjs.map +1 -0
  30. package/dist/chunk-CG53ASWX.mjs +729 -0
  31. package/dist/chunk-CG53ASWX.mjs.map +1 -0
  32. package/dist/{scanner-ETJAMIT7.js → chunk-DERI27QC.js} +448 -102
  33. package/dist/chunk-DERI27QC.js.map +1 -0
  34. package/dist/chunk-DYM5ML2V.mjs +1518 -0
  35. package/dist/chunk-DYM5ML2V.mjs.map +1 -0
  36. package/dist/chunk-FLZZOX44.js +1526 -0
  37. package/dist/chunk-FLZZOX44.js.map +1 -0
  38. package/dist/{chunk-7H6I3ECV.mjs → chunk-FQVGK746.mjs} +63 -3
  39. package/dist/chunk-FQVGK746.mjs.map +1 -0
  40. package/dist/{chunk-GQ6ZOU2N.mjs → chunk-JGQPAXTL.mjs} +4 -4
  41. package/dist/{chunk-GQ6ZOU2N.mjs.map → chunk-JGQPAXTL.mjs.map} +1 -1
  42. package/dist/{chunk-V3F5J6CV.js → chunk-JUEVN4Q4.js} +196 -7
  43. package/dist/chunk-JUEVN4Q4.js.map +1 -0
  44. package/dist/chunk-KKMGTT7F.mjs +968 -0
  45. package/dist/chunk-KKMGTT7F.mjs.map +1 -0
  46. package/dist/{chunk-XQJX252G.mjs → chunk-MB3WR5KJ.mjs} +28 -18
  47. package/dist/chunk-MB3WR5KJ.mjs.map +1 -0
  48. package/dist/{chunk-2IHTEKHU.mjs → chunk-QD5CN2OI.mjs} +16 -7
  49. package/dist/chunk-QD5CN2OI.mjs.map +1 -0
  50. package/dist/chunk-QD66FTXZ.mjs +278 -0
  51. package/dist/chunk-QD66FTXZ.mjs.map +1 -0
  52. package/dist/{chunk-SBVEYCSV.js → chunk-QQB4FO4Q.js} +7 -7
  53. package/dist/{chunk-SBVEYCSV.js.map → chunk-QQB4FO4Q.js.map} +1 -1
  54. package/dist/{generators-YZWIGHCO.js → chunk-S2GXR5HY.js} +26 -9
  55. package/dist/chunk-S2GXR5HY.js.map +1 -0
  56. package/dist/{chunk-O2OHHBUD.js → chunk-TDK7DLCH.js} +30 -20
  57. package/dist/chunk-TDK7DLCH.js.map +1 -0
  58. package/dist/chunk-UJQ73OS6.js +282 -0
  59. package/dist/chunk-UJQ73OS6.js.map +1 -0
  60. package/dist/{chunk-QP5NCO2E.js → chunk-VDI7KYME.js} +67 -2
  61. package/dist/chunk-VDI7KYME.js.map +1 -0
  62. package/dist/chunk-VOR53RUR.js +753 -0
  63. package/dist/chunk-VOR53RUR.js.map +1 -0
  64. package/dist/{chunk-GAJLEDRD.js → chunk-ZKJ7JKFV.js} +16 -7
  65. package/dist/chunk-ZKJ7JKFV.js.map +1 -0
  66. package/dist/chunk-ZSMWDLMK.js +63 -0
  67. package/dist/{chunk-EQCVQC35.js.map → chunk-ZSMWDLMK.js.map} +1 -1
  68. package/dist/cli/index.js +37269 -0
  69. package/dist/cli/index.js.map +1 -0
  70. package/dist/cli/index.mjs +37233 -0
  71. package/dist/cli/index.mjs.map +1 -0
  72. package/dist/commerce/index.js +1 -1
  73. package/dist/commerce/index.mjs +1 -1
  74. package/dist/commerce/server.d.mts +12 -3
  75. package/dist/commerce/server.d.ts +12 -3
  76. package/dist/commerce/server.js +71 -70
  77. package/dist/commerce/server.js.map +1 -1
  78. package/dist/commerce/server.mjs +71 -70
  79. package/dist/commerce/server.mjs.map +1 -1
  80. package/dist/engage/index.d.mts +6 -4
  81. package/dist/engage/index.d.ts +6 -4
  82. package/dist/engage/index.js +8 -4
  83. package/dist/engage/index.mjs +2 -2
  84. package/dist/forms/index.js +1 -1
  85. package/dist/forms/index.mjs +1 -1
  86. package/dist/generators-5EU4PTVF.js +33 -0
  87. package/dist/generators-5EU4PTVF.js.map +1 -0
  88. package/dist/generators-TYPILCWD.mjs +4 -0
  89. package/dist/generators-TYPILCWD.mjs.map +1 -0
  90. package/dist/images/index.js +11 -11
  91. package/dist/images/index.mjs +4 -4
  92. package/dist/index.d.mts +155 -5
  93. package/dist/index.d.ts +155 -5
  94. package/dist/index.js +979 -50
  95. package/dist/index.js.map +1 -1
  96. package/dist/index.mjs +821 -8
  97. package/dist/index.mjs.map +1 -1
  98. package/dist/llms/index.d.mts +657 -0
  99. package/dist/llms/index.d.ts +657 -0
  100. package/dist/llms/index.js +101 -0
  101. package/dist/llms/index.js.map +1 -0
  102. package/dist/llms/index.mjs +4 -0
  103. package/dist/llms/index.mjs.map +1 -0
  104. package/dist/migrator-ARLHUNB3.mjs +4 -0
  105. package/dist/migrator-ARLHUNB3.mjs.map +1 -0
  106. package/dist/migrator-VZLBH3VY.js +37 -0
  107. package/dist/migrator-VZLBH3VY.js.map +1 -0
  108. package/dist/redirects/index.js +1 -1
  109. package/dist/redirects/index.mjs +1 -1
  110. package/dist/reputation/index.d.mts +57 -0
  111. package/dist/reputation/index.d.ts +57 -0
  112. package/dist/reputation/index.js +21 -0
  113. package/dist/reputation/index.js.map +1 -0
  114. package/dist/reputation/index.mjs +4 -0
  115. package/dist/reputation/index.mjs.map +1 -0
  116. package/dist/{routing-BWjUF7lp.d.ts → routing-CF91y6NO.d.ts} +1 -1
  117. package/dist/{routing-CgmRi9tD.d.mts → routing-CIOFpFCB.d.mts} +1 -1
  118. package/dist/scanner-7ZMUM2P5.mjs +4 -0
  119. package/dist/scanner-7ZMUM2P5.mjs.map +1 -0
  120. package/dist/scanner-OY7UF3WA.js +53 -0
  121. package/dist/scanner-OY7UF3WA.js.map +1 -0
  122. package/dist/seo/index.d.mts +267 -7
  123. package/dist/seo/index.d.ts +267 -7
  124. package/dist/seo/index.js +432 -24
  125. package/dist/seo/index.js.map +1 -1
  126. package/dist/seo/index.mjs +400 -11
  127. package/dist/seo/index.mjs.map +1 -1
  128. package/dist/seo/server.d.mts +11 -4
  129. package/dist/seo/server.d.ts +11 -4
  130. package/dist/seo/server.js +17 -17
  131. package/dist/seo/server.mjs +3 -3
  132. package/dist/setup/client.js +1 -1
  133. package/dist/setup/client.mjs +1 -1
  134. package/dist/setup/index.js +3 -3
  135. package/dist/setup/index.mjs +2 -2
  136. package/dist/setup/server.js +3 -3
  137. package/dist/setup/server.mjs +2 -2
  138. package/dist/sitemap/index.js +2 -2
  139. package/dist/sitemap/index.js.map +1 -1
  140. package/dist/sitemap/index.mjs +2 -2
  141. package/dist/sitemap/index.mjs.map +1 -1
  142. package/dist/{types-C0pJGfbH.d.mts → types-D6FHAVWX.d.mts} +99 -3
  143. package/dist/{types-C0pJGfbH.d.ts → types-D6FHAVWX.d.ts} +99 -3
  144. package/dist/{types-BDojCvvL.d.mts → types-DI0jnhjJ.d.mts} +31 -8
  145. package/dist/{types-BDojCvvL.d.ts → types-DI0jnhjJ.d.ts} +31 -8
  146. package/dist/{types-BmzutFwy.d.ts → types-j8X4vUhB.d.mts} +19 -2
  147. package/dist/{types-BmzutFwy.d.mts → types-j8X4vUhB.d.ts} +19 -2
  148. package/dist/{web-vitals-BH55V7EJ.js → web-vitals-444RLW3B.js} +11 -11
  149. package/dist/{web-vitals-BH55V7EJ.js.map → web-vitals-444RLW3B.js.map} +1 -1
  150. package/dist/{web-vitals-RJYPWAR3.mjs → web-vitals-KPICZIEF.mjs} +3 -3
  151. package/dist/{web-vitals-RJYPWAR3.mjs.map → web-vitals-KPICZIEF.mjs.map} +1 -1
  152. package/package.json +22 -10
  153. package/dist/api-N35S3EES.js +0 -57
  154. package/dist/api-N35S3EES.js.map +0 -1
  155. package/dist/api-SYBTK7Z7.mjs +0 -4
  156. package/dist/api-SYBTK7Z7.mjs.map +0 -1
  157. package/dist/chunk-2IHTEKHU.mjs.map +0 -1
  158. package/dist/chunk-7H6I3ECV.mjs.map +0 -1
  159. package/dist/chunk-BGJLOJ7T.mjs +0 -605
  160. package/dist/chunk-BGJLOJ7T.mjs.map +0 -1
  161. package/dist/chunk-EQCVQC35.js +0 -35
  162. package/dist/chunk-FKVJOT2F.mjs.map +0 -1
  163. package/dist/chunk-GAJLEDRD.js.map +0 -1
  164. package/dist/chunk-NYKRE2FL.mjs +0 -31
  165. package/dist/chunk-O2OHHBUD.js.map +0 -1
  166. package/dist/chunk-QAYJV4KK.js +0 -608
  167. package/dist/chunk-QAYJV4KK.js.map +0 -1
  168. package/dist/chunk-QP5NCO2E.js.map +0 -1
  169. package/dist/chunk-V3F5J6CV.js.map +0 -1
  170. package/dist/chunk-XQJX252G.mjs.map +0 -1
  171. package/dist/generators-TO2FKJR6.mjs.map +0 -1
  172. package/dist/generators-YZWIGHCO.js.map +0 -1
  173. package/dist/migrator-V6KS75EA.mjs +0 -265
  174. package/dist/migrator-V6KS75EA.mjs.map +0 -1
  175. package/dist/migrator-XKM7YQCY.js +0 -272
  176. package/dist/migrator-XKM7YQCY.js.map +0 -1
  177. package/dist/scanner-AZV5I6US.mjs.map +0 -1
  178. package/dist/scanner-ETJAMIT7.js.map +0 -1
@@ -1,25 +1,1163 @@
1
- import '../chunk-NYKRE2FL.mjs';
2
- import { jsxs, jsx } from 'react/jsx-runtime';
3
- import { useState, useEffect } from 'react';
1
+ import '../chunk-4XPGGLVP.mjs';
2
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
3
+ import React, { useState, useEffect } from 'react';
4
4
 
5
- async function BlogPost({ projectId, slug, children }) {
6
- return /* @__PURE__ */ jsxs("div", { children: [
7
- /* @__PURE__ */ jsxs("p", { children: [
8
- "Blog post: ",
9
- slug
5
+ async function fetchBlogPost(apiUrl, apiKey, slug) {
6
+ try {
7
+ const response = await fetch(`${apiUrl}/public/blog/posts/${slug}`, {
8
+ headers: { "x-api-key": apiKey },
9
+ next: { revalidate: 60 }
10
+ });
11
+ if (!response.ok) {
12
+ if (response.status === 404) return null;
13
+ console.error("[Blog] Failed to fetch post:", response.statusText);
14
+ return null;
15
+ }
16
+ const data = await response.json();
17
+ return data.post;
18
+ } catch (error) {
19
+ console.error("[Blog] Error fetching post:", error);
20
+ return null;
21
+ }
22
+ }
23
+ async function fetchRelatedPosts(apiUrl, apiKey, postId, limit = 3) {
24
+ try {
25
+ const response = await fetch(`${apiUrl}/public/blog/related`, {
26
+ method: "POST",
27
+ headers: {
28
+ "Content-Type": "application/json",
29
+ "x-api-key": apiKey
30
+ },
31
+ body: JSON.stringify({ current_post_id: postId, limit }),
32
+ next: { revalidate: 300 }
33
+ });
34
+ if (!response.ok) return [];
35
+ const data = await response.json();
36
+ return data.posts || [];
37
+ } catch (error) {
38
+ console.error("[Blog] Error fetching related posts:", error);
39
+ return [];
40
+ }
41
+ }
42
+ function generateTableOfContents(html) {
43
+ const headingRegex = /<h([2-4])[^>]*(?:id="([^"]*)")?[^>]*>(.*?)<\/h[2-4]>/gi;
44
+ const items = [];
45
+ let match;
46
+ while ((match = headingRegex.exec(html)) !== null) {
47
+ const level = parseInt(match[1]);
48
+ const existingId = match[2];
49
+ const text = match[3].replace(/<[^>]*>/g, "");
50
+ const id = existingId || slugify(text);
51
+ items.push({ id, text, level });
52
+ }
53
+ return items;
54
+ }
55
+ function slugify(text) {
56
+ return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");
57
+ }
58
+ async function BlogPost({
59
+ apiUrl = process.env.NEXT_PUBLIC_UPTRADE_API_URL || "https://api.uptrademedia.com",
60
+ apiKey = process.env.NEXT_PUBLIC_UPTRADE_API_KEY || "",
61
+ slug,
62
+ showToc = true,
63
+ showRelated = true,
64
+ relatedCount = 3,
65
+ showAuthor = true,
66
+ basePath = "/blog",
67
+ className,
68
+ children
69
+ }) {
70
+ if (!apiKey) {
71
+ console.warn("[Blog] No API key configured");
72
+ return null;
73
+ }
74
+ const post = await fetchBlogPost(apiUrl, apiKey, slug);
75
+ if (!post) {
76
+ return /* @__PURE__ */ jsxs("div", { className, style: { textAlign: "center", padding: 60 }, children: [
77
+ /* @__PURE__ */ jsx("h1", { style: { fontSize: 24, marginBottom: 16 }, children: "Post Not Found" }),
78
+ /* @__PURE__ */ jsx("p", { style: { color: "#6b7280" }, children: "The blog post you're looking for doesn't exist or has been removed." }),
79
+ /* @__PURE__ */ jsx(
80
+ "a",
81
+ {
82
+ href: basePath,
83
+ style: {
84
+ display: "inline-block",
85
+ marginTop: 24,
86
+ padding: "12px 24px",
87
+ backgroundColor: "#3b82f6",
88
+ color: "#fff",
89
+ borderRadius: 8,
90
+ textDecoration: "none"
91
+ },
92
+ children: "\u2190 Back to Blog"
93
+ }
94
+ )
95
+ ] });
96
+ }
97
+ const content = post.content_html || post.content || "";
98
+ const tableOfContents = showToc ? generateTableOfContents(content) : [];
99
+ const relatedPosts = showRelated ? await fetchRelatedPosts(apiUrl, apiKey, post.id, relatedCount) : [];
100
+ if (children) {
101
+ return children({ post, tableOfContents, relatedPosts });
102
+ }
103
+ const date = post.published_at ? new Date(post.published_at).toLocaleDateString("en-US", {
104
+ month: "long",
105
+ day: "numeric",
106
+ year: "numeric"
107
+ }) : null;
108
+ return /* @__PURE__ */ jsxs("article", { className, children: [
109
+ /* @__PURE__ */ jsxs("header", { style: { marginBottom: 32 }, children: [
110
+ /* @__PURE__ */ jsxs("nav", { style: { marginBottom: 16, fontSize: 14, color: "#6b7280" }, children: [
111
+ /* @__PURE__ */ jsx("a", { href: basePath, style: { color: "#3b82f6", textDecoration: "none" }, children: "Blog" }),
112
+ post.category && /* @__PURE__ */ jsxs(Fragment, { children: [
113
+ /* @__PURE__ */ jsx("span", { style: { margin: "0 8px" }, children: "/" }),
114
+ /* @__PURE__ */ jsx(
115
+ "a",
116
+ {
117
+ href: `${basePath}?category=${post.category}`,
118
+ style: { color: "#3b82f6", textDecoration: "none" },
119
+ children: typeof post.category === "string" ? post.category : post.category?.name || "Uncategorized"
120
+ }
121
+ )
122
+ ] })
123
+ ] }),
124
+ /* @__PURE__ */ jsx("h1", { style: { fontSize: 36, fontWeight: 700, lineHeight: 1.2, marginBottom: 16 }, children: post.title }),
125
+ post.subtitle && /* @__PURE__ */ jsx("p", { style: { fontSize: 20, color: "#6b7280", marginBottom: 16 }, children: post.subtitle }),
126
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 16, flexWrap: "wrap" }, children: [
127
+ post.author && /* @__PURE__ */ jsxs("span", { style: { fontSize: 14, color: "#374151" }, children: [
128
+ "By ",
129
+ typeof post.author === "string" ? post.author : post.author.name
130
+ ] }),
131
+ date && /* @__PURE__ */ jsx("span", { style: { fontSize: 14, color: "#6b7280" }, children: date }),
132
+ post.reading_time_minutes && /* @__PURE__ */ jsxs("span", { style: { fontSize: 14, color: "#9ca3af" }, children: [
133
+ post.reading_time_minutes,
134
+ " min read"
135
+ ] })
136
+ ] })
137
+ ] }),
138
+ post.featured_image && /* @__PURE__ */ jsx("figure", { style: { margin: "0 0 32px" }, children: /* @__PURE__ */ jsx(
139
+ "img",
140
+ {
141
+ src: post.featured_image,
142
+ alt: post.featured_image_alt || post.title,
143
+ style: {
144
+ width: "100%",
145
+ maxHeight: 500,
146
+ objectFit: "cover",
147
+ borderRadius: 12
148
+ }
149
+ }
150
+ ) }),
151
+ /* @__PURE__ */ jsxs(
152
+ "div",
153
+ {
154
+ style: {
155
+ display: showToc && tableOfContents.length > 0 ? "grid" : "block",
156
+ gridTemplateColumns: showToc && tableOfContents.length > 0 ? "1fr 250px" : void 0,
157
+ gap: 48
158
+ },
159
+ children: [
160
+ /* @__PURE__ */ jsx(
161
+ "div",
162
+ {
163
+ className: "blog-content",
164
+ style: {
165
+ fontSize: 17,
166
+ lineHeight: 1.8,
167
+ color: "#374151"
168
+ },
169
+ dangerouslySetInnerHTML: { __html: content }
170
+ }
171
+ ),
172
+ showToc && tableOfContents.length > 0 && /* @__PURE__ */ jsxs(
173
+ "aside",
174
+ {
175
+ style: {
176
+ position: "sticky",
177
+ top: 100,
178
+ alignSelf: "start",
179
+ padding: 20,
180
+ backgroundColor: "#f9fafb",
181
+ borderRadius: 12
182
+ },
183
+ children: [
184
+ /* @__PURE__ */ jsx(
185
+ "h4",
186
+ {
187
+ style: {
188
+ margin: "0 0 12px",
189
+ fontSize: 12,
190
+ fontWeight: 600,
191
+ textTransform: "uppercase",
192
+ letterSpacing: "0.05em",
193
+ color: "#6b7280"
194
+ },
195
+ children: "On This Page"
196
+ }
197
+ ),
198
+ /* @__PURE__ */ jsx("ul", { style: { listStyle: "none", margin: 0, padding: 0 }, children: tableOfContents.map((item) => /* @__PURE__ */ jsx(
199
+ "li",
200
+ {
201
+ style: {
202
+ paddingLeft: (item.level - 2) * 12,
203
+ marginBottom: 8
204
+ },
205
+ children: /* @__PURE__ */ jsx(
206
+ "a",
207
+ {
208
+ href: `#${item.id}`,
209
+ style: {
210
+ fontSize: 14,
211
+ color: "#6b7280",
212
+ textDecoration: "none"
213
+ },
214
+ children: item.text
215
+ }
216
+ )
217
+ },
218
+ item.id
219
+ )) })
220
+ ]
221
+ }
222
+ )
223
+ ]
224
+ }
225
+ ),
226
+ post.tags && post.tags.length > 0 && /* @__PURE__ */ jsx("div", { style: { marginTop: 32, display: "flex", gap: 8, flexWrap: "wrap" }, children: post.tags.map((tag, index) => {
227
+ const tagName = typeof tag === "string" ? tag : tag?.name || "";
228
+ return /* @__PURE__ */ jsxs(
229
+ "a",
230
+ {
231
+ href: `${basePath}?tag=${tagName}`,
232
+ style: {
233
+ padding: "4px 12px",
234
+ backgroundColor: "#f3f4f6",
235
+ borderRadius: 9999,
236
+ fontSize: 13,
237
+ color: "#374151",
238
+ textDecoration: "none"
239
+ },
240
+ children: [
241
+ "#",
242
+ tagName
243
+ ]
244
+ },
245
+ `${tagName}-${index}`
246
+ );
247
+ }) }),
248
+ (post.faq_items ?? post.faqItems) && Array.isArray(post.faq_items ?? post.faqItems) && (post.faq_items ?? post.faqItems).length > 0 && /* @__PURE__ */ jsxs("section", { style: { marginTop: 48 }, children: [
249
+ /* @__PURE__ */ jsx("h2", { style: { fontSize: 24, fontWeight: 600, marginBottom: 24 }, children: "Frequently Asked Questions" }),
250
+ /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: 16 }, children: (post.faq_items ?? post.faqItems).map((faq, index) => /* @__PURE__ */ jsxs(
251
+ "details",
252
+ {
253
+ style: {
254
+ padding: 16,
255
+ backgroundColor: "#f9fafb",
256
+ borderRadius: 8
257
+ },
258
+ children: [
259
+ /* @__PURE__ */ jsx(
260
+ "summary",
261
+ {
262
+ style: {
263
+ fontWeight: 500,
264
+ cursor: "pointer",
265
+ listStyle: "none"
266
+ },
267
+ children: faq.question
268
+ }
269
+ ),
270
+ /* @__PURE__ */ jsx("p", { style: { marginTop: 12, color: "#6b7280" }, children: faq.answer })
271
+ ]
272
+ },
273
+ index
274
+ )) })
10
275
  ] }),
11
- /* @__PURE__ */ jsx("p", { children: "Coming soon..." })
276
+ showAuthor && post.author && typeof post.author === "object" && /* @__PURE__ */ jsx(AuthorSection, { author: normalizeAuthorForDisplay(post.author) }),
277
+ showRelated && relatedPosts.length > 0 && /* @__PURE__ */ jsxs("section", { style: { marginTop: 48 }, children: [
278
+ /* @__PURE__ */ jsx("h2", { style: { fontSize: 24, fontWeight: 600, marginBottom: 24 }, children: "Related Posts" }),
279
+ /* @__PURE__ */ jsx(
280
+ "div",
281
+ {
282
+ style: {
283
+ display: "grid",
284
+ gridTemplateColumns: "repeat(auto-fill, minmax(280px, 1fr))",
285
+ gap: 24
286
+ },
287
+ children: relatedPosts.map((relatedPost) => /* @__PURE__ */ jsxs(
288
+ "article",
289
+ {
290
+ style: {
291
+ backgroundColor: "#fff",
292
+ borderRadius: 12,
293
+ overflow: "hidden",
294
+ boxShadow: "0 1px 3px rgba(0,0,0,0.1)"
295
+ },
296
+ children: [
297
+ relatedPost.featured_image && /* @__PURE__ */ jsx("a", { href: `${basePath}/${relatedPost.slug}`, children: /* @__PURE__ */ jsx(
298
+ "img",
299
+ {
300
+ src: relatedPost.featured_image,
301
+ alt: relatedPost.title,
302
+ style: { width: "100%", height: 150, objectFit: "cover" }
303
+ }
304
+ ) }),
305
+ /* @__PURE__ */ jsxs("div", { style: { padding: 16 }, children: [
306
+ /* @__PURE__ */ jsx("h3", { style: { fontSize: 16, fontWeight: 600, marginBottom: 8 }, children: /* @__PURE__ */ jsx(
307
+ "a",
308
+ {
309
+ href: `${basePath}/${relatedPost.slug}`,
310
+ style: { color: "inherit", textDecoration: "none" },
311
+ children: relatedPost.title
312
+ }
313
+ ) }),
314
+ relatedPost.excerpt && /* @__PURE__ */ jsxs("p", { style: { fontSize: 14, color: "#6b7280", margin: 0 }, children: [
315
+ relatedPost.excerpt.slice(0, 100),
316
+ "..."
317
+ ] })
318
+ ] })
319
+ ]
320
+ },
321
+ relatedPost.id
322
+ ))
323
+ }
324
+ )
325
+ ] })
12
326
  ] });
13
327
  }
14
- async function BlogList({ projectId, options, children }) {
15
- return /* @__PURE__ */ jsxs("div", { children: [
16
- /* @__PURE__ */ jsxs("p", { children: [
17
- "Blog list for project: ",
18
- projectId
328
+ function normalizeAuthorForDisplay(author) {
329
+ const a = author;
330
+ const avatarUrl = a.avatar_url ?? a.image ?? a.image_url;
331
+ const socialLinks = a.social_links;
332
+ const socialProfiles = a.socialProfiles;
333
+ return {
334
+ id: a.id ?? "author",
335
+ project_id: a.project_id ?? "",
336
+ name: a.name ?? "Author",
337
+ slug: a.slug ?? "author",
338
+ bio: a.bio ?? void 0,
339
+ avatar_url: avatarUrl ?? void 0,
340
+ email: a.email ?? void 0,
341
+ website: a.website ?? a.url ?? void 0,
342
+ social_links: socialLinks ?? void 0,
343
+ is_active: a.is_active ?? true,
344
+ ...socialProfiles?.length ? { sameAs: socialProfiles } : {},
345
+ ...a.title ? { title: a.title } : {}
346
+ };
347
+ }
348
+ function AuthorSection({
349
+ author
350
+ }) {
351
+ return /* @__PURE__ */ jsxs(
352
+ "section",
353
+ {
354
+ style: {
355
+ marginTop: 48,
356
+ padding: 24,
357
+ backgroundColor: "#f9fafb",
358
+ borderRadius: 12,
359
+ display: "flex",
360
+ gap: 20,
361
+ alignItems: "flex-start"
362
+ },
363
+ children: [
364
+ author.avatar_url && /* @__PURE__ */ jsx(
365
+ "img",
366
+ {
367
+ src: author.avatar_url,
368
+ alt: author.name,
369
+ style: {
370
+ width: 80,
371
+ height: 80,
372
+ borderRadius: "50%",
373
+ objectFit: "cover"
374
+ }
375
+ }
376
+ ),
377
+ /* @__PURE__ */ jsxs("div", { children: [
378
+ /* @__PURE__ */ jsx("h3", { style: { margin: "0 0 4px", fontSize: 18, fontWeight: 600 }, children: author.name }),
379
+ "title" in author && author.title && /* @__PURE__ */ jsx("p", { style: { margin: "0 0 4px", fontSize: 14, color: "#6b7280" }, children: author.title }),
380
+ author.bio && /* @__PURE__ */ jsx("p", { style: { margin: "0 0 12px", color: "#6b7280", fontSize: 14 }, children: author.bio }),
381
+ author.social_links && /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 16 }, children: [
382
+ author.social_links.twitter && /* @__PURE__ */ jsx(
383
+ "a",
384
+ {
385
+ href: `https://twitter.com/${author.social_links.twitter}`,
386
+ target: "_blank",
387
+ rel: "noopener noreferrer",
388
+ style: { color: "#3b82f6", fontSize: 14 },
389
+ children: "Twitter"
390
+ }
391
+ ),
392
+ author.social_links.linkedin && /* @__PURE__ */ jsx(
393
+ "a",
394
+ {
395
+ href: author.social_links.linkedin,
396
+ target: "_blank",
397
+ rel: "noopener noreferrer",
398
+ style: { color: "#3b82f6", fontSize: 14 },
399
+ children: "LinkedIn"
400
+ }
401
+ )
402
+ ] }),
403
+ "sameAs" in author && author.sameAs && author.sameAs.length > 0 && !author.social_links && /* @__PURE__ */ jsx("div", { style: { display: "flex", gap: 16, flexWrap: "wrap" }, children: author.sameAs.map((url, i) => /* @__PURE__ */ jsx(
404
+ "a",
405
+ {
406
+ href: url,
407
+ target: "_blank",
408
+ rel: "noopener noreferrer",
409
+ style: { color: "#3b82f6", fontSize: 14 },
410
+ children: "Profile"
411
+ },
412
+ i
413
+ )) })
414
+ ] })
415
+ ]
416
+ }
417
+ );
418
+ }
419
+ async function fetchBlogList(params) {
420
+ const {
421
+ apiUrl,
422
+ apiKey,
423
+ category,
424
+ tag,
425
+ author,
426
+ featured,
427
+ search,
428
+ page = 1,
429
+ perPage = 12,
430
+ orderBy = "published_at",
431
+ order = "desc"
432
+ } = params;
433
+ const queryParams = new URLSearchParams();
434
+ if (category) queryParams.set("category", category);
435
+ if (tag) queryParams.set("tag", tag);
436
+ if (author) queryParams.set("author", author);
437
+ if (featured) queryParams.set("featured", "true");
438
+ if (search) queryParams.set("search", search);
439
+ queryParams.set("page", String(page));
440
+ queryParams.set("per_page", String(perPage));
441
+ queryParams.set("order_by", orderBy);
442
+ queryParams.set("order", order);
443
+ try {
444
+ const response = await fetch(`${apiUrl}/public/blog/posts?${queryParams}`, {
445
+ headers: {
446
+ "x-api-key": apiKey
447
+ },
448
+ next: { revalidate: 60 }
449
+ // Revalidate every 60 seconds
450
+ });
451
+ if (!response.ok) {
452
+ console.error("[Blog] Failed to fetch posts:", response.statusText);
453
+ return {
454
+ posts: [],
455
+ pagination: {
456
+ page: 1,
457
+ perPage: 12,
458
+ total: 0,
459
+ totalPages: 0,
460
+ hasNext: false,
461
+ hasPrev: false
462
+ }
463
+ };
464
+ }
465
+ const data = await response.json();
466
+ return {
467
+ posts: data.posts || [],
468
+ pagination: {
469
+ page: data.pagination?.page || 1,
470
+ perPage: data.pagination?.per_page || 12,
471
+ total: data.pagination?.total || 0,
472
+ totalPages: data.pagination?.total_pages || 0,
473
+ hasNext: data.pagination?.has_next || false,
474
+ hasPrev: data.pagination?.has_prev || false
475
+ }
476
+ };
477
+ } catch (error) {
478
+ console.error("[Blog] Error fetching posts:", error);
479
+ return {
480
+ posts: [],
481
+ pagination: {
482
+ page: 1,
483
+ perPage: 12,
484
+ total: 0,
485
+ totalPages: 0,
486
+ hasNext: false,
487
+ hasPrev: false
488
+ }
489
+ };
490
+ }
491
+ }
492
+ async function fetchCategories(apiUrl, apiKey) {
493
+ try {
494
+ const response = await fetch(`${apiUrl}/public/blog/categories`, {
495
+ headers: { "x-api-key": apiKey },
496
+ next: { revalidate: 300 }
497
+ // Cache for 5 minutes
498
+ });
499
+ if (!response.ok) return [];
500
+ const data = await response.json();
501
+ return data.categories || [];
502
+ } catch (error) {
503
+ console.error("[Blog] Error fetching categories:", error);
504
+ return [];
505
+ }
506
+ }
507
+ async function BlogList({
508
+ apiUrl = process.env.NEXT_PUBLIC_UPTRADE_API_URL || "https://api.uptrademedia.com",
509
+ apiKey = process.env.NEXT_PUBLIC_UPTRADE_API_KEY || "",
510
+ category,
511
+ tag,
512
+ author,
513
+ featured,
514
+ search,
515
+ page = 1,
516
+ perPage = 12,
517
+ orderBy = "published_at",
518
+ order = "desc",
519
+ showCategoryFilter = false,
520
+ showPagination = true,
521
+ className,
522
+ basePath = "/blog",
523
+ renderPost,
524
+ children
525
+ }) {
526
+ if (!apiKey) {
527
+ console.warn("[Blog] No API key configured");
528
+ return null;
529
+ }
530
+ const [blogData, categories] = await Promise.all([
531
+ fetchBlogList({
532
+ apiUrl,
533
+ apiKey,
534
+ category,
535
+ tag,
536
+ author,
537
+ featured,
538
+ search,
539
+ page,
540
+ perPage,
541
+ orderBy,
542
+ order
543
+ }),
544
+ showCategoryFilter ? fetchCategories(apiUrl, apiKey) : Promise.resolve([])
545
+ ]);
546
+ if (children) {
547
+ return children({ posts: blogData.posts, pagination: blogData.pagination, categories });
548
+ }
549
+ const { posts, pagination } = blogData;
550
+ if (posts.length === 0) {
551
+ return /* @__PURE__ */ jsx("div", { className, style: { textAlign: "center", padding: 40 }, children: /* @__PURE__ */ jsx("p", { style: { color: "#6b7280" }, children: "No posts found." }) });
552
+ }
553
+ return /* @__PURE__ */ jsxs("div", { className, children: [
554
+ showCategoryFilter && categories.length > 0 && /* @__PURE__ */ jsxs("nav", { style: { marginBottom: 24, display: "flex", gap: 8, flexWrap: "wrap" }, children: [
555
+ /* @__PURE__ */ jsx(
556
+ "a",
557
+ {
558
+ href: basePath,
559
+ style: {
560
+ padding: "6px 12px",
561
+ borderRadius: 9999,
562
+ fontSize: 14,
563
+ textDecoration: "none",
564
+ backgroundColor: !category ? "#3b82f6" : "#f3f4f6",
565
+ color: !category ? "#fff" : "#374151"
566
+ },
567
+ children: "All"
568
+ }
569
+ ),
570
+ categories.map((cat) => /* @__PURE__ */ jsxs(
571
+ "a",
572
+ {
573
+ href: `${basePath}?category=${cat.slug}`,
574
+ style: {
575
+ padding: "6px 12px",
576
+ borderRadius: 9999,
577
+ fontSize: 14,
578
+ textDecoration: "none",
579
+ backgroundColor: category === cat.slug ? "#3b82f6" : "#f3f4f6",
580
+ color: category === cat.slug ? "#fff" : "#374151"
581
+ },
582
+ children: [
583
+ cat.name,
584
+ " (",
585
+ cat.post_count,
586
+ ")"
587
+ ]
588
+ },
589
+ cat.slug
590
+ ))
19
591
  ] }),
20
- /* @__PURE__ */ jsx("p", { children: "Coming soon..." })
592
+ /* @__PURE__ */ jsx(
593
+ "div",
594
+ {
595
+ style: {
596
+ display: "grid",
597
+ gridTemplateColumns: "repeat(auto-fill, minmax(320px, 1fr))",
598
+ gap: 24
599
+ },
600
+ children: posts.map(
601
+ (post) => renderPost ? /* @__PURE__ */ jsx(React.Fragment, { children: renderPost(post) }, post.id) : /* @__PURE__ */ jsx(BlogPostCard, { post, basePath }, post.id)
602
+ )
603
+ }
604
+ ),
605
+ showPagination && pagination.totalPages > 1 && /* @__PURE__ */ jsxs(
606
+ "nav",
607
+ {
608
+ style: {
609
+ marginTop: 40,
610
+ display: "flex",
611
+ justifyContent: "center",
612
+ gap: 8
613
+ },
614
+ children: [
615
+ pagination.hasPrev && /* @__PURE__ */ jsx(
616
+ "a",
617
+ {
618
+ href: buildPaginationUrl(basePath, page - 1, category),
619
+ style: paginationLinkStyle,
620
+ children: "\u2190 Previous"
621
+ }
622
+ ),
623
+ /* @__PURE__ */ jsxs("span", { style: { padding: "8px 16px", color: "#6b7280" }, children: [
624
+ "Page ",
625
+ pagination.page,
626
+ " of ",
627
+ pagination.totalPages
628
+ ] }),
629
+ pagination.hasNext && /* @__PURE__ */ jsx(
630
+ "a",
631
+ {
632
+ href: buildPaginationUrl(basePath, page + 1, category),
633
+ style: paginationLinkStyle,
634
+ children: "Next \u2192"
635
+ }
636
+ )
637
+ ]
638
+ }
639
+ )
640
+ ] });
641
+ }
642
+ function BlogPostCard({ post, basePath }) {
643
+ const date = post.published_at ? new Date(post.published_at).toLocaleDateString("en-US", {
644
+ month: "long",
645
+ day: "numeric",
646
+ year: "numeric"
647
+ }) : null;
648
+ return /* @__PURE__ */ jsxs(
649
+ "article",
650
+ {
651
+ style: {
652
+ backgroundColor: "#fff",
653
+ borderRadius: 12,
654
+ overflow: "hidden",
655
+ boxShadow: "0 1px 3px rgba(0,0,0,0.1)",
656
+ transition: "box-shadow 0.2s, transform 0.2s"
657
+ },
658
+ children: [
659
+ post.featured_image && /* @__PURE__ */ jsx("a", { href: `${basePath}/${post.slug}`, children: /* @__PURE__ */ jsx(
660
+ "img",
661
+ {
662
+ src: post.featured_image,
663
+ alt: post.featured_image_alt || post.title,
664
+ style: {
665
+ width: "100%",
666
+ height: 200,
667
+ objectFit: "cover"
668
+ }
669
+ }
670
+ ) }),
671
+ /* @__PURE__ */ jsxs("div", { style: { padding: 20 }, children: [
672
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 12, marginBottom: 12 }, children: [
673
+ post.category && /* @__PURE__ */ jsx(
674
+ "span",
675
+ {
676
+ style: {
677
+ padding: "2px 8px",
678
+ borderRadius: 4,
679
+ fontSize: 12,
680
+ fontWeight: 500,
681
+ backgroundColor: "#eff6ff",
682
+ color: "#3b82f6",
683
+ textTransform: "uppercase"
684
+ },
685
+ children: typeof post.category === "string" ? post.category : post.category?.name || "Uncategorized"
686
+ }
687
+ ),
688
+ date && /* @__PURE__ */ jsx("span", { style: { fontSize: 13, color: "#6b7280" }, children: date })
689
+ ] }),
690
+ /* @__PURE__ */ jsx("h3", { style: { margin: "0 0 8px", fontSize: 18, fontWeight: 600, lineHeight: 1.4 }, children: /* @__PURE__ */ jsx(
691
+ "a",
692
+ {
693
+ href: `${basePath}/${post.slug}`,
694
+ style: { color: "inherit", textDecoration: "none" },
695
+ children: post.title
696
+ }
697
+ ) }),
698
+ post.excerpt && /* @__PURE__ */ jsx(
699
+ "p",
700
+ {
701
+ style: {
702
+ margin: "0 0 16px",
703
+ fontSize: 14,
704
+ color: "#6b7280",
705
+ lineHeight: 1.6,
706
+ display: "-webkit-box",
707
+ WebkitLineClamp: 3,
708
+ WebkitBoxOrient: "vertical",
709
+ overflow: "hidden"
710
+ },
711
+ children: post.excerpt
712
+ }
713
+ ),
714
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [
715
+ post.author && /* @__PURE__ */ jsxs("span", { style: { fontSize: 13, color: "#6b7280" }, children: [
716
+ "By ",
717
+ typeof post.author === "string" ? post.author : post.author.name
718
+ ] }),
719
+ post.reading_time_minutes && /* @__PURE__ */ jsxs("span", { style: { fontSize: 13, color: "#9ca3af" }, children: [
720
+ post.reading_time_minutes,
721
+ " min read"
722
+ ] })
723
+ ] })
724
+ ] })
725
+ ]
726
+ }
727
+ );
728
+ }
729
+ function buildPaginationUrl(basePath, page, category) {
730
+ const params = new URLSearchParams();
731
+ params.set("page", String(page));
732
+ if (category) params.set("category", category);
733
+ return `${basePath}?${params}`;
734
+ }
735
+ var paginationLinkStyle = {
736
+ padding: "8px 16px",
737
+ borderRadius: 8,
738
+ backgroundColor: "#3b82f6",
739
+ color: "#fff",
740
+ textDecoration: "none",
741
+ fontSize: 14,
742
+ fontWeight: 500
743
+ };
744
+ async function fetchRecentPosts(apiUrl, apiKey, limit = 5) {
745
+ try {
746
+ const response = await fetch(`${apiUrl}/public/blog/recent?limit=${limit}`, {
747
+ headers: { "x-api-key": apiKey },
748
+ next: { revalidate: 300 }
749
+ });
750
+ if (!response.ok) return [];
751
+ const data = await response.json();
752
+ return data.posts || [];
753
+ } catch (error) {
754
+ console.error("[Blog] Error fetching recent posts:", error);
755
+ return [];
756
+ }
757
+ }
758
+ async function fetchCategories2(apiUrl, apiKey) {
759
+ try {
760
+ const response = await fetch(`${apiUrl}/public/blog/categories`, {
761
+ headers: { "x-api-key": apiKey },
762
+ next: { revalidate: 300 }
763
+ });
764
+ if (!response.ok) return [];
765
+ const data = await response.json();
766
+ return data.categories || [];
767
+ } catch (error) {
768
+ console.error("[Blog] Error fetching categories:", error);
769
+ return [];
770
+ }
771
+ }
772
+ async function fetchTags(apiUrl, apiKey) {
773
+ try {
774
+ const response = await fetch(`${apiUrl}/public/blog/tags`, {
775
+ headers: { "x-api-key": apiKey },
776
+ next: { revalidate: 300 }
777
+ });
778
+ if (!response.ok) return [];
779
+ const data = await response.json();
780
+ return data.tags || [];
781
+ } catch (error) {
782
+ console.error("[Blog] Error fetching tags:", error);
783
+ return [];
784
+ }
785
+ }
786
+ async function BlogSidebar({
787
+ apiUrl = process.env.NEXT_PUBLIC_UPTRADE_API_URL || "https://api.uptrademedia.com",
788
+ apiKey = process.env.NEXT_PUBLIC_UPTRADE_API_KEY || "",
789
+ showCategories = true,
790
+ showRecentPosts = true,
791
+ recentPostsCount = 5,
792
+ showTags = true,
793
+ showSearch = true,
794
+ basePath = "/blog",
795
+ className,
796
+ currentCategory,
797
+ children
798
+ }) {
799
+ if (!apiKey) {
800
+ console.warn("[Blog] No API key configured for sidebar");
801
+ return null;
802
+ }
803
+ const [categories, recentPosts, tags] = await Promise.all([
804
+ showCategories ? fetchCategories2(apiUrl, apiKey) : Promise.resolve([]),
805
+ showRecentPosts ? fetchRecentPosts(apiUrl, apiKey, recentPostsCount) : Promise.resolve([]),
806
+ showTags ? fetchTags(apiUrl, apiKey) : Promise.resolve([])
807
+ ]);
808
+ return /* @__PURE__ */ jsxs("aside", { className, style: { display: "flex", flexDirection: "column", gap: 32 }, children: [
809
+ showSearch && /* @__PURE__ */ jsx(SearchWidget, { basePath }),
810
+ showCategories && categories.length > 0 && /* @__PURE__ */ jsx(
811
+ CategoriesWidget,
812
+ {
813
+ categories,
814
+ basePath,
815
+ currentCategory
816
+ }
817
+ ),
818
+ showRecentPosts && recentPosts.length > 0 && /* @__PURE__ */ jsx(RecentPostsWidget, { posts: recentPosts, basePath }),
819
+ showTags && tags.length > 0 && /* @__PURE__ */ jsx(TagsWidget, { tags, basePath }),
820
+ children
21
821
  ] });
22
822
  }
823
+ function SearchWidget({ basePath }) {
824
+ return /* @__PURE__ */ jsxs("div", { style: widgetStyle, children: [
825
+ /* @__PURE__ */ jsx("h4", { style: widgetTitleStyle, children: "Search" }),
826
+ /* @__PURE__ */ jsx("form", { action: basePath, method: "get", children: /* @__PURE__ */ jsx(
827
+ "input",
828
+ {
829
+ type: "search",
830
+ name: "search",
831
+ placeholder: "Search posts...",
832
+ style: {
833
+ width: "100%",
834
+ padding: "10px 12px",
835
+ border: "1px solid #e5e7eb",
836
+ borderRadius: 8,
837
+ fontSize: 14
838
+ }
839
+ }
840
+ ) })
841
+ ] });
842
+ }
843
+ function CategoriesWidget({
844
+ categories,
845
+ basePath,
846
+ currentCategory
847
+ }) {
848
+ return /* @__PURE__ */ jsxs("div", { style: widgetStyle, children: [
849
+ /* @__PURE__ */ jsx("h4", { style: widgetTitleStyle, children: "Categories" }),
850
+ /* @__PURE__ */ jsxs("ul", { style: { listStyle: "none", margin: 0, padding: 0 }, children: [
851
+ /* @__PURE__ */ jsx("li", { style: { marginBottom: 8 }, children: /* @__PURE__ */ jsx(
852
+ "a",
853
+ {
854
+ href: basePath,
855
+ style: {
856
+ ...categoryLinkStyle,
857
+ fontWeight: !currentCategory ? 600 : 400,
858
+ color: !currentCategory ? "#3b82f6" : "#374151"
859
+ },
860
+ children: "All Posts"
861
+ }
862
+ ) }),
863
+ categories.map((cat) => /* @__PURE__ */ jsx("li", { style: { marginBottom: 8 }, children: /* @__PURE__ */ jsxs(
864
+ "a",
865
+ {
866
+ href: `${basePath}?category=${cat.slug}`,
867
+ style: {
868
+ ...categoryLinkStyle,
869
+ fontWeight: currentCategory === cat.slug ? 600 : 400,
870
+ color: currentCategory === cat.slug ? "#3b82f6" : "#374151"
871
+ },
872
+ children: [
873
+ cat.name,
874
+ /* @__PURE__ */ jsxs("span", { style: { color: "#9ca3af", marginLeft: 8 }, children: [
875
+ "(",
876
+ cat.post_count,
877
+ ")"
878
+ ] })
879
+ ]
880
+ }
881
+ ) }, cat.slug))
882
+ ] })
883
+ ] });
884
+ }
885
+ function RecentPostsWidget({
886
+ posts,
887
+ basePath
888
+ }) {
889
+ return /* @__PURE__ */ jsxs("div", { style: widgetStyle, children: [
890
+ /* @__PURE__ */ jsx("h4", { style: widgetTitleStyle, children: "Recent Posts" }),
891
+ /* @__PURE__ */ jsx("ul", { style: { listStyle: "none", margin: 0, padding: 0 }, children: posts.map((post) => {
892
+ const date = post.published_at ? new Date(post.published_at).toLocaleDateString("en-US", {
893
+ month: "short",
894
+ day: "numeric"
895
+ }) : null;
896
+ return /* @__PURE__ */ jsx(
897
+ "li",
898
+ {
899
+ style: {
900
+ marginBottom: 16,
901
+ paddingBottom: 16,
902
+ borderBottom: "1px solid #e5e7eb"
903
+ },
904
+ children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 12 }, children: [
905
+ post.featured_image && /* @__PURE__ */ jsx("a", { href: `${basePath}/${post.slug}`, children: /* @__PURE__ */ jsx(
906
+ "img",
907
+ {
908
+ src: post.featured_image,
909
+ alt: "",
910
+ style: {
911
+ width: 64,
912
+ height: 48,
913
+ objectFit: "cover",
914
+ borderRadius: 6,
915
+ flexShrink: 0
916
+ }
917
+ }
918
+ ) }),
919
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [
920
+ /* @__PURE__ */ jsx(
921
+ "a",
922
+ {
923
+ href: `${basePath}/${post.slug}`,
924
+ style: {
925
+ fontSize: 14,
926
+ fontWeight: 500,
927
+ color: "#374151",
928
+ textDecoration: "none",
929
+ display: "-webkit-box",
930
+ WebkitLineClamp: 2,
931
+ WebkitBoxOrient: "vertical",
932
+ overflow: "hidden"
933
+ },
934
+ children: post.title
935
+ }
936
+ ),
937
+ date && /* @__PURE__ */ jsx("span", { style: { fontSize: 12, color: "#9ca3af", display: "block", marginTop: 4 }, children: date })
938
+ ] })
939
+ ] })
940
+ },
941
+ post.id
942
+ );
943
+ }) })
944
+ ] });
945
+ }
946
+ function TagsWidget({
947
+ tags,
948
+ basePath
949
+ }) {
950
+ return /* @__PURE__ */ jsxs("div", { style: widgetStyle, children: [
951
+ /* @__PURE__ */ jsx("h4", { style: widgetTitleStyle, children: "Popular Tags" }),
952
+ /* @__PURE__ */ jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: 8 }, children: tags.slice(0, 15).map((tag) => /* @__PURE__ */ jsx(
953
+ "a",
954
+ {
955
+ href: `${basePath}?tag=${tag.slug}`,
956
+ style: {
957
+ padding: "4px 10px",
958
+ backgroundColor: "#f3f4f6",
959
+ borderRadius: 9999,
960
+ fontSize: 12,
961
+ color: "#374151",
962
+ textDecoration: "none",
963
+ transition: "background-color 0.2s"
964
+ },
965
+ children: tag.name
966
+ },
967
+ tag.slug
968
+ )) })
969
+ ] });
970
+ }
971
+ function NewsletterWidget({
972
+ title = "Subscribe to Our Newsletter",
973
+ description = "Get the latest posts delivered straight to your inbox.",
974
+ buttonText = "Subscribe"
975
+ }) {
976
+ return /* @__PURE__ */ jsxs("div", { style: { ...widgetStyle, backgroundColor: "#eff6ff" }, children: [
977
+ /* @__PURE__ */ jsx("h4", { style: { ...widgetTitleStyle, color: "#1e40af" }, children: title }),
978
+ /* @__PURE__ */ jsx("p", { style: { fontSize: 14, color: "#6b7280", marginBottom: 16 }, children: description }),
979
+ /* @__PURE__ */ jsxs(
980
+ "form",
981
+ {
982
+ onSubmit: (e) => {
983
+ e.preventDefault();
984
+ },
985
+ style: { display: "flex", gap: 8 },
986
+ children: [
987
+ /* @__PURE__ */ jsx(
988
+ "input",
989
+ {
990
+ type: "email",
991
+ name: "email",
992
+ placeholder: "Enter your email",
993
+ required: true,
994
+ style: {
995
+ flex: 1,
996
+ padding: "10px 12px",
997
+ border: "1px solid #bfdbfe",
998
+ borderRadius: 8,
999
+ fontSize: 14
1000
+ }
1001
+ }
1002
+ ),
1003
+ /* @__PURE__ */ jsx(
1004
+ "button",
1005
+ {
1006
+ type: "submit",
1007
+ style: {
1008
+ padding: "10px 16px",
1009
+ backgroundColor: "#3b82f6",
1010
+ color: "#fff",
1011
+ border: "none",
1012
+ borderRadius: 8,
1013
+ fontSize: 14,
1014
+ fontWeight: 500,
1015
+ cursor: "pointer"
1016
+ },
1017
+ children: buttonText
1018
+ }
1019
+ )
1020
+ ]
1021
+ }
1022
+ )
1023
+ ] });
1024
+ }
1025
+ var widgetStyle = {
1026
+ padding: 20,
1027
+ backgroundColor: "#f9fafb",
1028
+ borderRadius: 12
1029
+ };
1030
+ var widgetTitleStyle = {
1031
+ margin: "0 0 16px",
1032
+ fontSize: 16,
1033
+ fontWeight: 600,
1034
+ color: "#111827"
1035
+ };
1036
+ var categoryLinkStyle = {
1037
+ display: "flex",
1038
+ alignItems: "center",
1039
+ fontSize: 14,
1040
+ textDecoration: "none"
1041
+ };
1042
+ async function BlogLayout({
1043
+ apiUrl = process.env.NEXT_PUBLIC_UPTRADE_API_URL || "https://api.uptrademedia.com",
1044
+ apiKey = process.env.NEXT_PUBLIC_UPTRADE_API_KEY || "",
1045
+ layout = "sidebar-right",
1046
+ showSidebar = true,
1047
+ sidebarProps = {},
1048
+ hero,
1049
+ maxWidth = 1280,
1050
+ basePath = "/blog",
1051
+ className,
1052
+ currentCategory,
1053
+ children
1054
+ }) {
1055
+ const hasSidebar = showSidebar && layout !== "full-width";
1056
+ return /* @__PURE__ */ jsxs("div", { className, children: [
1057
+ hero && /* @__PURE__ */ jsx(
1058
+ "section",
1059
+ {
1060
+ style: {
1061
+ padding: "60px 20px",
1062
+ backgroundColor: hero.backgroundColor || "#1e3a5f",
1063
+ backgroundImage: hero.backgroundImage ? `url(${hero.backgroundImage})` : void 0,
1064
+ backgroundSize: "cover",
1065
+ backgroundPosition: "center",
1066
+ color: "#fff",
1067
+ textAlign: "center"
1068
+ },
1069
+ children: /* @__PURE__ */ jsxs("div", { style: { maxWidth, margin: "0 auto" }, children: [
1070
+ hero.title && /* @__PURE__ */ jsx(
1071
+ "h1",
1072
+ {
1073
+ style: {
1074
+ fontSize: "clamp(32px, 5vw, 48px)",
1075
+ fontWeight: 700,
1076
+ marginBottom: 16
1077
+ },
1078
+ children: hero.title
1079
+ }
1080
+ ),
1081
+ hero.subtitle && /* @__PURE__ */ jsx(
1082
+ "p",
1083
+ {
1084
+ style: {
1085
+ fontSize: "clamp(16px, 2vw, 20px)",
1086
+ opacity: 0.9,
1087
+ maxWidth: 600,
1088
+ margin: "0 auto"
1089
+ },
1090
+ children: hero.subtitle
1091
+ }
1092
+ )
1093
+ ] })
1094
+ }
1095
+ ),
1096
+ /* @__PURE__ */ jsx(
1097
+ "div",
1098
+ {
1099
+ style: {
1100
+ maxWidth,
1101
+ margin: "0 auto",
1102
+ padding: "40px 20px"
1103
+ },
1104
+ children: /* @__PURE__ */ jsxs(
1105
+ "div",
1106
+ {
1107
+ style: {
1108
+ display: hasSidebar ? "grid" : "block",
1109
+ gridTemplateColumns: hasSidebar ? layout === "sidebar-left" ? "300px 1fr" : "1fr 300px" : void 0,
1110
+ gap: 48
1111
+ },
1112
+ children: [
1113
+ hasSidebar && layout === "sidebar-left" && /* @__PURE__ */ jsx(
1114
+ BlogSidebar,
1115
+ {
1116
+ apiUrl,
1117
+ apiKey,
1118
+ basePath,
1119
+ currentCategory,
1120
+ ...sidebarProps
1121
+ }
1122
+ ),
1123
+ /* @__PURE__ */ jsx("main", { style: { minWidth: 0 }, children }),
1124
+ hasSidebar && layout === "sidebar-right" && /* @__PURE__ */ jsx(
1125
+ BlogSidebar,
1126
+ {
1127
+ apiUrl,
1128
+ apiKey,
1129
+ basePath,
1130
+ currentCategory,
1131
+ ...sidebarProps
1132
+ }
1133
+ )
1134
+ ]
1135
+ }
1136
+ )
1137
+ }
1138
+ )
1139
+ ] });
1140
+ }
1141
+ async function BlogPage({ listComponent, ...layoutProps }) {
1142
+ return /* @__PURE__ */ jsx(BlogLayout, { ...layoutProps, children: listComponent });
1143
+ }
1144
+ async function BlogPostPage({ postComponent, ...layoutProps }) {
1145
+ return /* @__PURE__ */ jsx(BlogLayout, { ...layoutProps, showSidebar: false, layout: "full-width", children: /* @__PURE__ */ jsx("div", { style: { maxWidth: 800, margin: "0 auto" }, children: postComponent }) });
1146
+ }
1147
+ async function CategoryPage({
1148
+ category,
1149
+ categoryName,
1150
+ listComponent,
1151
+ hero,
1152
+ ...layoutProps
1153
+ }) {
1154
+ const categoryHero = hero || {
1155
+ title: categoryName || category,
1156
+ subtitle: `Browse all posts in ${categoryName || category}`,
1157
+ backgroundColor: "#1e3a5f"
1158
+ };
1159
+ return /* @__PURE__ */ jsx(BlogLayout, { ...layoutProps, hero: categoryHero, currentCategory: category, children: listComponent });
1160
+ }
23
1161
  function AuthorCard({ author, showBio = true, showSocial = true, className }) {
24
1162
  return /* @__PURE__ */ jsxs("div", { className, style: { display: "flex", gap: 16, alignItems: "flex-start" }, children: [
25
1163
  author.avatar_url && /* @__PURE__ */ jsx(
@@ -46,7 +1184,7 @@ function AuthorCard({ author, showBio = true, showSocial = true, className }) {
46
1184
  ] })
47
1185
  ] });
48
1186
  }
49
- async function fetchRelatedPosts(apiUrl, apiKey, currentPostId, limit) {
1187
+ async function fetchRelatedPosts2(apiUrl, apiKey, currentPostId, limit) {
50
1188
  try {
51
1189
  const response = await fetch(`${apiUrl}/api/public/blog/related`, {
52
1190
  method: "POST",
@@ -82,7 +1220,7 @@ async function RelatedPosts({
82
1220
  console.warn("[Blog] No API key configured for RelatedPosts");
83
1221
  return null;
84
1222
  }
85
- const posts = await fetchRelatedPosts(apiUrl, apiKey, currentPostId, limit);
1223
+ const posts = await fetchRelatedPosts2(apiUrl, apiKey, currentPostId, limit);
86
1224
  if (posts.length === 0) return null;
87
1225
  return /* @__PURE__ */ jsxs("section", { className, children: [
88
1226
  /* @__PURE__ */ jsx("h3", { style: { marginBottom: 16 }, children: "Related Posts" }),
@@ -189,6 +1327,6 @@ function TableOfContents({
189
1327
  ] });
190
1328
  }
191
1329
 
192
- export { AuthorCard, BlogList, BlogPost, RelatedPosts, TableOfContents };
1330
+ export { AuthorCard, BlogLayout, BlogList, BlogPage, BlogPost, BlogPostPage, BlogSidebar, CategoryPage, NewsletterWidget, RelatedPosts, TableOfContents };
193
1331
  //# sourceMappingURL=index.mjs.map
194
1332
  //# sourceMappingURL=index.mjs.map