@fullstackdatasolutions/articles 0.8.2 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +237 -0
  2. package/README.md +209 -78
  3. package/dist/index.cjs +635 -274
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.d.cts +164 -56
  6. package/dist/index.d.ts +164 -56
  7. package/dist/index.js +614 -250
  8. package/dist/index.js.map +1 -1
  9. package/dist/nextjs.cjs +113 -38
  10. package/dist/nextjs.cjs.map +1 -1
  11. package/dist/nextjs.d.cts +71 -0
  12. package/dist/nextjs.d.ts +71 -0
  13. package/dist/nextjs.js +113 -38
  14. package/dist/nextjs.js.map +1 -1
  15. package/dist/server.cjs +394 -52
  16. package/dist/server.cjs.map +1 -1
  17. package/dist/server.d.cts +96 -6
  18. package/dist/server.d.ts +96 -6
  19. package/dist/server.js +382 -52
  20. package/dist/server.js.map +1 -1
  21. package/package.json +8 -5
  22. package/src/ArticleContent.tsx +8 -3
  23. package/src/ArticleDetailHero.tsx +27 -2
  24. package/src/ArticleSchemas.tsx +27 -27
  25. package/src/AuthorArticlesPage.tsx +60 -0
  26. package/src/AuthorCard.tsx +112 -0
  27. package/src/AuthorDetailHero.tsx +56 -0
  28. package/src/Breadcrumb.tsx +78 -0
  29. package/src/CategoryArticlesPage.tsx +62 -11
  30. package/src/__tests__/ArticleContent.test.tsx +18 -2
  31. package/src/__tests__/ArticleDetailHero.test.tsx +21 -1
  32. package/src/__tests__/ArticleSchemas.test.tsx +47 -2
  33. package/src/__tests__/AuthorArticlesPage.test.tsx +74 -0
  34. package/src/__tests__/AuthorCard.test.tsx +98 -0
  35. package/src/__tests__/AuthorDetailHero.test.tsx +51 -0
  36. package/src/__tests__/CategoryArticlesPage.test.tsx +31 -5
  37. package/src/__tests__/authorUtils.test.ts +89 -0
  38. package/src/__tests__/markdown.test.ts +79 -3
  39. package/src/__tests__/renderMdx.test.tsx +57 -0
  40. package/src/__tests__/seoUtils-authors.test.ts +160 -0
  41. package/src/__tests__/seoUtils.test.ts +106 -0
  42. package/src/__tests__/server-articles.test.ts +174 -3
  43. package/src/articleTypes.ts +33 -0
  44. package/src/articlesConfig.ts +67 -0
  45. package/src/authorUtils.ts +95 -0
  46. package/src/index.ts +32 -9
  47. package/src/markdown.ts +67 -8
  48. package/src/renderMdx.tsx +6 -3
  49. package/src/seoUtils.ts +279 -6
  50. package/src/server-articles.ts +124 -34
  51. package/src/server.ts +21 -2
package/dist/index.js CHANGED
@@ -90,44 +90,177 @@ function ArticleCategoryGrid({ categories, pageSize = 8 }) {
90
90
  ] }) });
91
91
  }
92
92
 
93
- // src/ArticleSchemas.tsx
93
+ // src/authorUtils.ts
94
+ function getAuthorUrl(author) {
95
+ var _a;
96
+ return (_a = author.url) != null ? _a : `/articles/authors/${author.slug}`;
97
+ }
98
+ function getAuthorAvatar(author, config) {
99
+ if (!author.avatar) return void 0;
100
+ if (author.avatar.startsWith("http://") || author.avatar.startsWith("https://")) {
101
+ return author.avatar;
102
+ }
103
+ const path = `/articles/authors/${author.slug}/${author.avatar.replace(/^\/+/, "")}`;
104
+ if (!config) return path;
105
+ return `${config.siteUrl.replace(/\/$/, "")}${path}`;
106
+ }
107
+ function getAuthorSameAs(author) {
108
+ return getAuthorSocialLinks(author).map((link) => link.href);
109
+ }
110
+ function normalizeHandle(value) {
111
+ return value.replace(/^@/, "");
112
+ }
113
+ function normalizeUrl(value, baseUrl) {
114
+ if (value.startsWith("http://") || value.startsWith("https://")) return value;
115
+ if (!baseUrl) return value;
116
+ return `${baseUrl}${normalizeHandle(value)}`;
117
+ }
118
+ function getConfiguredSocialLinks(social) {
119
+ var _a, _b;
120
+ return [
121
+ { label: "Website", href: (_a = social.website) != null ? _a : "" },
122
+ {
123
+ label: "Facebook",
124
+ href: social.facebook ? normalizeUrl(social.facebook, "https://www.facebook.com/") : ""
125
+ },
126
+ {
127
+ label: "Twitter",
128
+ href: social.twitter ? normalizeUrl(social.twitter, "https://twitter.com/") : ""
129
+ },
130
+ { label: "X", href: social.x ? normalizeUrl(social.x, "https://x.com/") : "" },
131
+ {
132
+ label: "LinkedIn",
133
+ href: social.linkedin ? normalizeUrl(social.linkedin, "https://www.linkedin.com/in/") : ""
134
+ },
135
+ {
136
+ label: "Instagram",
137
+ href: social.instagram ? normalizeUrl(social.instagram, "https://www.instagram.com/") : ""
138
+ },
139
+ {
140
+ label: "YouTube",
141
+ href: social.youtube ? normalizeUrl(social.youtube, "https://www.youtube.com/") : ""
142
+ },
143
+ {
144
+ label: "TikTok",
145
+ href: social.tiktok ? normalizeUrl(social.tiktok, "https://www.tiktok.com/@") : ""
146
+ },
147
+ {
148
+ label: "GitHub",
149
+ href: social.github ? normalizeUrl(social.github, "https://github.com/") : ""
150
+ },
151
+ {
152
+ label: "Bluesky",
153
+ href: social.bluesky ? normalizeUrl(social.bluesky, "https://bsky.app/profile/") : ""
154
+ },
155
+ {
156
+ label: "Threads",
157
+ href: social.threads ? normalizeUrl(social.threads, "https://www.threads.net/@") : ""
158
+ },
159
+ { label: "Mastodon", href: social.mastodon ? normalizeUrl(social.mastodon) : "" },
160
+ {
161
+ label: "Medium",
162
+ href: social.medium ? normalizeUrl(social.medium, "https://medium.com/@") : ""
163
+ },
164
+ { label: "Newsletter", href: (_b = social.newsletter) != null ? _b : "" }
165
+ ];
166
+ }
167
+ function getAuthorSocialLinks(author) {
168
+ var _a;
169
+ const social = author.social;
170
+ if (!social) return [];
171
+ const configuredLinks = getConfiguredSocialLinks(social);
172
+ const otherLinks = Object.entries((_a = social.other) != null ? _a : {}).map(([label, href]) => ({ label, href }));
173
+ return [...configuredLinks, ...otherLinks].filter((link) => link.href.trim().length > 0);
174
+ }
175
+
176
+ // src/Breadcrumb.tsx
177
+ import Link2 from "next/link";
94
178
  import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
179
+ function buildBreadcrumbSchema(items) {
180
+ return {
181
+ "@context": "https://schema.org",
182
+ "@type": "BreadcrumbList",
183
+ itemListElement: items.map((item, index) => __spreadValues({
184
+ "@type": "ListItem",
185
+ position: index + 1,
186
+ name: item.name
187
+ }, item.url && { item: item.url }))
188
+ };
189
+ }
190
+ function getDisplayItems(items) {
191
+ if (items.length <= 4) return [...items];
192
+ return [items[0], { name: "..." }, ...items.slice(-2)];
193
+ }
194
+ function Breadcrumb({
195
+ items,
196
+ className = "",
197
+ showSchema = true,
198
+ separator = ">"
199
+ }) {
200
+ if (items.length === 0) return null;
201
+ const displayItems = getDisplayItems(items);
202
+ return /* @__PURE__ */ jsxs2(Fragment, { children: [
203
+ /* @__PURE__ */ jsx2(
204
+ "nav",
205
+ {
206
+ "aria-label": "Breadcrumb",
207
+ className: `border-b border-border bg-background/80 px-4 py-3 text-sm text-muted-foreground ${className}`,
208
+ children: /* @__PURE__ */ jsx2("ol", { className: "mx-auto flex max-w-7xl items-center gap-2 overflow-hidden", children: displayItems.map((item, index) => {
209
+ const isLast = index === displayItems.length - 1;
210
+ const key = `${item.name}-${index}`;
211
+ return /* @__PURE__ */ jsxs2("li", { className: "flex min-w-0 items-center gap-2", children: [
212
+ index > 0 && /* @__PURE__ */ jsx2("span", { "aria-hidden": "true", children: separator }),
213
+ item.url && !isLast ? /* @__PURE__ */ jsx2(Link2, { href: item.url, className: "truncate hover:text-foreground", children: item.name }) : /* @__PURE__ */ jsx2("span", { className: "truncate", "aria-current": isLast ? "page" : void 0, children: item.name })
214
+ ] }, key);
215
+ }) })
216
+ }
217
+ ),
218
+ showSchema && /* @__PURE__ */ jsx2(
219
+ "script",
220
+ {
221
+ type: "application/ld+json",
222
+ dangerouslySetInnerHTML: { __html: JSON.stringify(buildBreadcrumbSchema(items)) }
223
+ }
224
+ )
225
+ ] });
226
+ }
227
+ function BreadcrumbSchema({ items }) {
228
+ return /* @__PURE__ */ jsx2(Breadcrumb, { items, showSchema: true, className: "sr-only" });
229
+ }
230
+
231
+ // src/ArticleSchemas.tsx
232
+ import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
233
+ function getPersonSchemas(article, authors) {
234
+ let resolvedAuthors = [];
235
+ if (authors == null ? void 0 : authors.length) {
236
+ resolvedAuthors = [...authors];
237
+ } else if (article.author) {
238
+ resolvedAuthors = [{ name: article.author, slug: "", bio: "" }];
239
+ }
240
+ return resolvedAuthors.map((author) => __spreadValues(__spreadValues({
241
+ "@type": "Person",
242
+ name: author.name
243
+ }, author.url && { url: author.url }), getAuthorSameAs(author).length > 0 && { sameAs: getAuthorSameAs(author) }));
244
+ }
95
245
  function ArticleSchema({
96
246
  article,
97
247
  articleUrl,
98
248
  siteName,
99
- showAuthor = true
249
+ showAuthor = true,
250
+ authors
100
251
  }) {
252
+ const personSchemas = getPersonSchemas(article, authors);
101
253
  const schema = __spreadProps(__spreadValues(__spreadValues({
102
254
  "@context": "https://schema.org",
103
255
  "@type": "Article",
104
256
  headline: article.title,
105
257
  description: article.excerpt,
106
258
  image: article.featuredImage
107
- }, article.date && { datePublished: new Date(article.date).toISOString() }), showAuthor && { author: { "@type": "Person", name: article.author } }), {
259
+ }, article.date && { datePublished: new Date(article.date).toISOString() }), showAuthor && personSchemas.length > 0 && { author: personSchemas }), {
108
260
  publisher: { "@type": "Organization", name: siteName },
109
261
  mainEntityOfPage: { "@type": "WebPage", "@id": articleUrl }
110
262
  });
111
- return /* @__PURE__ */ jsx2(
112
- "script",
113
- {
114
- type: "application/ld+json",
115
- dangerouslySetInnerHTML: { __html: JSON.stringify(schema) }
116
- }
117
- );
118
- }
119
- function BreadcrumbSchema({ items }) {
120
- const schema = {
121
- "@context": "https://schema.org",
122
- "@type": "BreadcrumbList",
123
- itemListElement: items.map((item, index) => ({
124
- "@type": "ListItem",
125
- position: index + 1,
126
- name: item.name,
127
- item: item.url
128
- }))
129
- };
130
- return /* @__PURE__ */ jsx2(
263
+ return /* @__PURE__ */ jsx3(
131
264
  "script",
132
265
  {
133
266
  type: "application/ld+json",
@@ -140,32 +273,34 @@ function ArticleSEO({
140
273
  articleUrl,
141
274
  siteName,
142
275
  siteLogo,
143
- showAuthor = true
276
+ showAuthor = true,
277
+ authors
144
278
  }) {
145
279
  const publishedAt = article.date ? new Date(article.date).toISOString() : void 0;
146
280
  const modifiedAt = article.lastmod ? new Date(article.lastmod).toISOString() : publishedAt;
281
+ const personSchemas = getPersonSchemas(article, authors);
147
282
  const structuredData = __spreadValues(__spreadProps(__spreadValues(__spreadValues(__spreadValues({
148
283
  "@context": "https://schema.org",
149
284
  "@type": article.articleType || "Article",
150
285
  mainEntityOfPage: { "@type": "WebPage", "@id": articleUrl },
151
286
  headline: article.title,
152
287
  image: article.featuredImage ? { "@type": "ImageObject", url: article.featuredImage } : void 0
153
- }, publishedAt && { datePublished: publishedAt }), modifiedAt && { dateModified: modifiedAt }), showAuthor && { author: { "@type": "Person", name: article.author } }), {
288
+ }, publishedAt && { datePublished: publishedAt }), modifiedAt && { dateModified: modifiedAt }), showAuthor && personSchemas.length > 0 && { author: personSchemas }), {
154
289
  publisher: __spreadValues({
155
290
  "@type": "Organization",
156
291
  name: siteName
157
292
  }, siteLogo && { logo: { "@type": "ImageObject", url: siteLogo } }),
158
293
  description: article.excerpt
159
294
  }), article.series && { isPartOf: { "@type": "Blog", name: article.series } });
160
- return /* @__PURE__ */ jsxs2(Fragment, { children: [
161
- /* @__PURE__ */ jsx2(
295
+ return /* @__PURE__ */ jsxs3(Fragment2, { children: [
296
+ /* @__PURE__ */ jsx3(
162
297
  "script",
163
298
  {
164
299
  type: "application/ld+json",
165
300
  dangerouslySetInnerHTML: { __html: JSON.stringify(structuredData) }
166
301
  }
167
302
  ),
168
- article.faq && article.faq.length > 0 && /* @__PURE__ */ jsx2(
303
+ article.faq && article.faq.length > 0 && /* @__PURE__ */ jsx3(
169
304
  "script",
170
305
  {
171
306
  type: "application/ld+json",
@@ -182,7 +317,7 @@ function ArticleSEO({
182
317
  }
183
318
  }
184
319
  ),
185
- article.howTo && article.howTo.length > 0 && /* @__PURE__ */ jsx2(
320
+ article.howTo && article.howTo.length > 0 && /* @__PURE__ */ jsx3(
186
321
  "script",
187
322
  {
188
323
  type: "application/ld+json",
@@ -212,7 +347,7 @@ function FAQPageSchema({ items }) {
212
347
  acceptedAnswer: { "@type": "Answer", text: answer }
213
348
  }))
214
349
  };
215
- return /* @__PURE__ */ jsx2(
350
+ return /* @__PURE__ */ jsx3(
216
351
  "script",
217
352
  {
218
353
  type: "application/ld+json",
@@ -234,7 +369,7 @@ function CollectionPageSchema({
234
369
  url,
235
370
  numberOfItems: articleCount
236
371
  };
237
- return /* @__PURE__ */ jsx2(
372
+ return /* @__PURE__ */ jsx3(
238
373
  "script",
239
374
  {
240
375
  type: "application/ld+json",
@@ -245,17 +380,17 @@ function CollectionPageSchema({
245
380
 
246
381
  // src/ArticleSearchBar.tsx
247
382
  import { Search, X } from "lucide-react";
248
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
383
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
249
384
  function ArticleSearchBar({
250
385
  value,
251
386
  onChange,
252
387
  disabled,
253
388
  resultCount
254
389
  }) {
255
- return /* @__PURE__ */ jsx3("section", { className: "py-8 bg-background border-b border-border", children: /* @__PURE__ */ jsxs3("div", { className: "max-w-4xl mx-auto px-4 sm:px-6 lg:px-8", children: [
256
- /* @__PURE__ */ jsxs3("div", { className: "relative", children: [
257
- /* @__PURE__ */ jsx3(Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 text-muted-foreground h-5 w-5" }),
258
- /* @__PURE__ */ jsx3(
390
+ return /* @__PURE__ */ jsx4("section", { className: "py-8 bg-background border-b border-border", children: /* @__PURE__ */ jsxs4("div", { className: "max-w-4xl mx-auto px-4 sm:px-6 lg:px-8", children: [
391
+ /* @__PURE__ */ jsxs4("div", { className: "relative", children: [
392
+ /* @__PURE__ */ jsx4(Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 text-muted-foreground h-5 w-5" }),
393
+ /* @__PURE__ */ jsx4(
259
394
  "input",
260
395
  {
261
396
  type: "text",
@@ -266,44 +401,44 @@ function ArticleSearchBar({
266
401
  className: "flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 pl-10 pr-10 py-3 text-lg"
267
402
  }
268
403
  ),
269
- value && /* @__PURE__ */ jsx3(
404
+ value && /* @__PURE__ */ jsx4(
270
405
  "button",
271
406
  {
272
407
  type: "button",
273
408
  onClick: () => onChange(""),
274
409
  "aria-label": "Clear search",
275
410
  className: "absolute right-3 top-1/2 transform -translate-y-1/2 text-muted-foreground hover:text-foreground",
276
- children: /* @__PURE__ */ jsx3(X, { className: "h-5 w-5" })
411
+ children: /* @__PURE__ */ jsx4(X, { className: "h-5 w-5" })
277
412
  }
278
413
  )
279
414
  ] }),
280
- value && /* @__PURE__ */ jsx3("div", { className: "mt-2 text-sm text-muted-foreground", children: resultCount === 0 ? "No articles found matching your search." : `Found ${resultCount} article${resultCount === 1 ? "" : "s"} matching "${value}"` })
415
+ value && /* @__PURE__ */ jsx4("div", { className: "mt-2 text-sm text-muted-foreground", children: resultCount === 0 ? "No articles found matching your search." : `Found ${resultCount} article${resultCount === 1 ? "" : "s"} matching "${value}"` })
281
416
  ] }) });
282
417
  }
283
418
 
284
419
  // src/ArticlesHero.tsx
285
- import Link2 from "next/link";
286
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
420
+ import Link3 from "next/link";
421
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
287
422
  var DEFAULT_TITLE = "Vox Populus Insights";
288
423
  var DEFAULT_DESCRIPTION = "Expert analysis, campaign strategies, and voter engagement insights from the frontlines of democracy.";
289
424
  function ArticlesHero({
290
425
  title = DEFAULT_TITLE,
291
426
  description = DEFAULT_DESCRIPTION
292
427
  }) {
293
- return /* @__PURE__ */ jsx4("section", { className: "bg-linear-to-r from-gray-50 to-gray-100 py-16 md:py-24", children: /* @__PURE__ */ jsx4("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: /* @__PURE__ */ jsxs4("div", { className: "max-w-3xl mx-auto text-center", children: [
294
- /* @__PURE__ */ jsx4("h1", { className: "text-4xl md:text-5xl font-bold text-foreground mb-6", children: title }),
295
- /* @__PURE__ */ jsx4("p", { className: "text-xl text-muted-foreground mb-8", children: description }),
296
- /* @__PURE__ */ jsxs4("div", { className: "flex flex-col sm:flex-row gap-4 justify-center", children: [
297
- /* @__PURE__ */ jsx4(
298
- Link2,
428
+ return /* @__PURE__ */ jsx5("section", { className: "bg-linear-to-r from-gray-50 to-gray-100 py-16 md:py-24", children: /* @__PURE__ */ jsx5("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: /* @__PURE__ */ jsxs5("div", { className: "max-w-3xl mx-auto text-center", children: [
429
+ /* @__PURE__ */ jsx5("h1", { className: "text-4xl md:text-5xl font-bold text-foreground mb-6", children: title }),
430
+ /* @__PURE__ */ jsx5("p", { className: "text-xl text-muted-foreground mb-8", children: description }),
431
+ /* @__PURE__ */ jsxs5("div", { className: "flex flex-col sm:flex-row gap-4 justify-center", children: [
432
+ /* @__PURE__ */ jsx5(
433
+ Link3,
299
434
  {
300
435
  href: "#latest",
301
436
  className: "inline-flex items-center justify-center px-4 py-2 bg-primary hover:bg-primary/90 text-primary-foreground rounded-md font-medium text-sm transition-colors",
302
437
  children: "Browse Latest Articles"
303
438
  }
304
439
  ),
305
- /* @__PURE__ */ jsx4(
306
- Link2,
440
+ /* @__PURE__ */ jsx5(
441
+ Link3,
307
442
  {
308
443
  href: "/contact",
309
444
  className: "inline-flex items-center justify-center px-4 py-2 border border-primary text-primary hover:bg-primary/10 rounded-md font-medium text-sm transition-colors",
@@ -315,44 +450,44 @@ function ArticlesHero({
315
450
  }
316
451
 
317
452
  // src/FeaturedArticle.tsx
318
- import Link3 from "next/link";
453
+ import Link4 from "next/link";
319
454
  import Image2 from "next/image";
320
455
  import { ArrowRight, Calendar, Clock, User } from "lucide-react";
321
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
456
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
322
457
  function FeaturedArticle({ article, showAuthor = true }) {
323
- return /* @__PURE__ */ jsx5("section", { className: "py-16 bg-background", children: /* @__PURE__ */ jsx5("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: /* @__PURE__ */ jsxs5("div", { className: "grid lg:grid-cols-2 gap-12 items-center", children: [
324
- /* @__PURE__ */ jsxs5("div", { children: [
325
- /* @__PURE__ */ jsx5("span", { className: "inline-block bg-primary/10 text-primary text-sm font-medium px-3 py-1 rounded-full mb-4", children: "FEATURED ARTICLE" }),
326
- /* @__PURE__ */ jsx5("h2", { className: "text-3xl font-bold text-foreground mb-4", children: article.title }),
327
- /* @__PURE__ */ jsx5("p", { className: "text-lg text-muted-foreground mb-6", children: article.excerpt }),
328
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-6 text-sm text-muted-foreground mb-6", children: [
329
- article.date && /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2", children: [
330
- /* @__PURE__ */ jsx5(Calendar, { className: "h-4 w-4" }),
331
- /* @__PURE__ */ jsx5("span", { children: article.date })
458
+ return /* @__PURE__ */ jsx6("section", { className: "py-16 bg-background", children: /* @__PURE__ */ jsx6("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: /* @__PURE__ */ jsxs6("div", { className: "grid lg:grid-cols-2 gap-12 items-center", children: [
459
+ /* @__PURE__ */ jsxs6("div", { children: [
460
+ /* @__PURE__ */ jsx6("span", { className: "inline-block bg-primary/10 text-primary text-sm font-medium px-3 py-1 rounded-full mb-4", children: "FEATURED ARTICLE" }),
461
+ /* @__PURE__ */ jsx6("h2", { className: "text-3xl font-bold text-foreground mb-4", children: article.title }),
462
+ /* @__PURE__ */ jsx6("p", { className: "text-lg text-muted-foreground mb-6", children: article.excerpt }),
463
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-6 text-sm text-muted-foreground mb-6", children: [
464
+ article.date && /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
465
+ /* @__PURE__ */ jsx6(Calendar, { className: "h-4 w-4" }),
466
+ /* @__PURE__ */ jsx6("span", { children: article.date })
332
467
  ] }),
333
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2", children: [
334
- /* @__PURE__ */ jsx5(Clock, { className: "h-4 w-4" }),
335
- /* @__PURE__ */ jsx5("span", { children: article.readTime })
468
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
469
+ /* @__PURE__ */ jsx6(Clock, { className: "h-4 w-4" }),
470
+ /* @__PURE__ */ jsx6("span", { children: article.readTime })
336
471
  ] }),
337
- showAuthor && /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2", children: [
338
- /* @__PURE__ */ jsx5(User, { className: "h-4 w-4" }),
339
- /* @__PURE__ */ jsx5("span", { children: article.author })
472
+ showAuthor && /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
473
+ /* @__PURE__ */ jsx6(User, { className: "h-4 w-4" }),
474
+ /* @__PURE__ */ jsx6("span", { children: article.author })
340
475
  ] })
341
476
  ] }),
342
- /* @__PURE__ */ jsxs5(
343
- Link3,
477
+ /* @__PURE__ */ jsxs6(
478
+ Link4,
344
479
  {
345
480
  href: `/articles/${article.slug}`,
346
481
  className: "inline-flex items-center justify-center px-4 py-2 bg-primary hover:bg-primary/90 text-primary-foreground rounded-md font-medium text-sm transition-colors",
347
482
  children: [
348
483
  "Read Full Article",
349
- /* @__PURE__ */ jsx5(ArrowRight, { className: "ml-2 h-4 w-4" })
484
+ /* @__PURE__ */ jsx6(ArrowRight, { className: "ml-2 h-4 w-4" })
350
485
  ]
351
486
  }
352
487
  )
353
488
  ] }),
354
- /* @__PURE__ */ jsxs5("div", { className: "bg-card rounded-lg p-8", children: [
355
- /* @__PURE__ */ jsx5(
489
+ /* @__PURE__ */ jsxs6("div", { className: "bg-card rounded-lg p-8", children: [
490
+ /* @__PURE__ */ jsx6(
356
491
  Image2,
357
492
  {
358
493
  src: article.featuredImage,
@@ -362,7 +497,7 @@ function FeaturedArticle({ article, showAuthor = true }) {
362
497
  className: "w-full h-64 object-cover rounded-lg mb-4"
363
498
  }
364
499
  ),
365
- /* @__PURE__ */ jsx5("div", { className: "flex gap-2", children: /* @__PURE__ */ jsx5("span", { className: "bg-primary/10 text-primary text-xs font-medium px-2 py-1 rounded", children: article.category }) })
500
+ /* @__PURE__ */ jsx6("div", { className: "flex gap-2", children: /* @__PURE__ */ jsx6("span", { className: "bg-primary/10 text-primary text-xs font-medium px-2 py-1 rounded", children: article.category }) })
366
501
  ] })
367
502
  ] }) }) });
368
503
  }
@@ -375,12 +510,12 @@ import { useState as useState2, useEffect as useEffect2 } from "react";
375
510
 
376
511
  // src/ArticleCard.tsx
377
512
  import Image3 from "next/image";
378
- import Link4 from "next/link";
513
+ import Link5 from "next/link";
379
514
  import { ArrowRight as ArrowRight2, Calendar as Calendar2, Clock as Clock2 } from "lucide-react";
380
- import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
515
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
381
516
  function ArticleCard({ article }) {
382
- return /* @__PURE__ */ jsxs6("div", { className: "rounded-lg border border-border bg-card text-card-foreground shadow-sm hover:shadow-lg transition-shadow duration-300", children: [
383
- /* @__PURE__ */ jsx6("div", { className: "p-0", children: /* @__PURE__ */ jsx6(
517
+ return /* @__PURE__ */ jsxs7("div", { className: "rounded-lg border border-border bg-card text-card-foreground shadow-sm hover:shadow-lg transition-shadow duration-300", children: [
518
+ /* @__PURE__ */ jsx7("div", { className: "p-0", children: /* @__PURE__ */ jsx7(
384
519
  Image3,
385
520
  {
386
521
  src: article.featuredImage,
@@ -390,35 +525,35 @@ function ArticleCard({ article }) {
390
525
  height: 200
391
526
  }
392
527
  ) }),
393
- /* @__PURE__ */ jsxs6("div", { className: "p-6", children: [
394
- /* @__PURE__ */ jsx6("div", { className: "flex gap-2 mb-3", children: /* @__PURE__ */ jsx6("span", { className: "bg-primary/10 text-primary text-xs font-medium px-2 py-1 rounded", children: article.category }) }),
395
- /* @__PURE__ */ jsx6("h3", { className: "text-lg font-semibold leading-none tracking-tight mb-2", children: /* @__PURE__ */ jsx6(
396
- Link4,
528
+ /* @__PURE__ */ jsxs7("div", { className: "p-6", children: [
529
+ /* @__PURE__ */ jsx7("div", { className: "flex gap-2 mb-3", children: /* @__PURE__ */ jsx7("span", { className: "bg-primary/10 text-primary text-xs font-medium px-2 py-1 rounded", children: article.category }) }),
530
+ /* @__PURE__ */ jsx7("h3", { className: "text-lg font-semibold leading-none tracking-tight mb-2", children: /* @__PURE__ */ jsx7(
531
+ Link5,
397
532
  {
398
533
  href: `/articles/${article.slug}`,
399
534
  className: "hover:text-indigo-600 transition-colors",
400
535
  children: article.title
401
536
  }
402
537
  ) }),
403
- /* @__PURE__ */ jsx6("p", { className: "text-muted-foreground mb-4 line-clamp-3", children: article.excerpt }),
404
- /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between text-sm text-muted-foreground border-t pt-4", children: [
405
- /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-3", children: [
406
- article.date && /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
407
- /* @__PURE__ */ jsx6(Calendar2, { className: "h-3 w-3" }),
408
- /* @__PURE__ */ jsx6("span", { children: article.date })
538
+ /* @__PURE__ */ jsx7("p", { className: "text-muted-foreground mb-4 line-clamp-3", children: article.excerpt }),
539
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between text-sm text-muted-foreground border-t pt-4", children: [
540
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-3", children: [
541
+ article.date && /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", children: [
542
+ /* @__PURE__ */ jsx7(Calendar2, { className: "h-3 w-3" }),
543
+ /* @__PURE__ */ jsx7("span", { children: article.date })
409
544
  ] }),
410
- /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
411
- /* @__PURE__ */ jsx6(Clock2, { className: "h-3 w-3" }),
412
- /* @__PURE__ */ jsx6("span", { children: article.readTime })
545
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", children: [
546
+ /* @__PURE__ */ jsx7(Clock2, { className: "h-3 w-3" }),
547
+ /* @__PURE__ */ jsx7("span", { children: article.readTime })
413
548
  ] })
414
549
  ] }),
415
- /* @__PURE__ */ jsx6(
416
- Link4,
550
+ /* @__PURE__ */ jsx7(
551
+ Link5,
417
552
  {
418
553
  href: `/articles/${article.slug}`,
419
554
  className: "inline-flex items-center justify-center h-8 w-8 p-0 rounded-md hover:bg-accent transition-colors",
420
555
  "aria-label": `Read ${article.title}`,
421
- children: /* @__PURE__ */ jsx6(ArrowRight2, { className: "h-4 w-4" })
556
+ children: /* @__PURE__ */ jsx7(ArrowRight2, { className: "h-4 w-4" })
422
557
  }
423
558
  )
424
559
  ] })
@@ -427,7 +562,7 @@ function ArticleCard({ article }) {
427
562
  }
428
563
 
429
564
  // src/LatestArticles.tsx
430
- import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
565
+ import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
431
566
  function LatestArticles({ articles, pageSize }) {
432
567
  const [visibleCount, setVisibleCount] = useState2(pageSize);
433
568
  useEffect2(() => {
@@ -435,9 +570,9 @@ function LatestArticles({ articles, pageSize }) {
435
570
  }, [articles, pageSize]);
436
571
  const visible = articles.slice(0, visibleCount);
437
572
  const hasMore = visibleCount < articles.length;
438
- return /* @__PURE__ */ jsxs7("div", { children: [
439
- /* @__PURE__ */ jsx7("div", { className: "grid md:grid-cols-2 lg:grid-cols-3 gap-8", children: visible.map((article) => /* @__PURE__ */ jsx7(ArticleCard, { article }, article.slug)) }),
440
- hasMore && /* @__PURE__ */ jsx7("div", { className: "mt-10 text-center", children: /* @__PURE__ */ jsx7(
573
+ return /* @__PURE__ */ jsxs8("div", { children: [
574
+ /* @__PURE__ */ jsx8("div", { className: "grid md:grid-cols-2 lg:grid-cols-3 gap-8", children: visible.map((article) => /* @__PURE__ */ jsx8(ArticleCard, { article }, article.slug)) }),
575
+ hasMore && /* @__PURE__ */ jsx8("div", { className: "mt-10 text-center", children: /* @__PURE__ */ jsx8(
441
576
  "button",
442
577
  {
443
578
  type: "button",
@@ -450,14 +585,14 @@ function LatestArticles({ articles, pageSize }) {
450
585
  }
451
586
 
452
587
  // src/LatestArticlesSection.tsx
453
- import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
588
+ import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
454
589
  function DescriptionText({
455
590
  searchQuery,
456
591
  count
457
592
  }) {
458
593
  const pluralSuffix = count === 1 ? "" : "s";
459
594
  const text = searchQuery ? `Found ${count} article${pluralSuffix} matching your search.` : "Stay informed with our latest insights on voter engagement, campaign strategies, and civic technology.";
460
- return /* @__PURE__ */ jsx8("p", { className: "text-lg text-muted-foreground", children: text });
595
+ return /* @__PURE__ */ jsx9("p", { className: "text-lg text-muted-foreground", children: text });
461
596
  }
462
597
  function LatestArticlesSection({
463
598
  articles,
@@ -465,20 +600,20 @@ function LatestArticlesSection({
465
600
  onClearSearch,
466
601
  pageSize = 6
467
602
  }) {
468
- return /* @__PURE__ */ jsx8("section", { id: "latest", className: "py-16 bg-muted/50", children: /* @__PURE__ */ jsxs8("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: [
469
- /* @__PURE__ */ jsxs8("div", { className: "text-center mb-12", children: [
470
- /* @__PURE__ */ jsx8("h2", { className: "text-3xl font-bold text-foreground mb-4", children: searchQuery ? "Search Results" : "Latest Articles" }),
471
- /* @__PURE__ */ jsx8(DescriptionText, { searchQuery, count: articles.length })
603
+ return /* @__PURE__ */ jsx9("section", { id: "latest", className: "py-16 bg-muted/50", children: /* @__PURE__ */ jsxs9("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: [
604
+ /* @__PURE__ */ jsxs9("div", { className: "text-center mb-12", children: [
605
+ /* @__PURE__ */ jsx9("h2", { className: "text-3xl font-bold text-foreground mb-4", children: searchQuery ? "Search Results" : "Latest Articles" }),
606
+ /* @__PURE__ */ jsx9(DescriptionText, { searchQuery, count: articles.length })
472
607
  ] }),
473
- articles.length === 0 && searchQuery ? /* @__PURE__ */ jsx8("div", { className: "text-center py-12", children: /* @__PURE__ */ jsxs8("div", { className: "max-w-md mx-auto", children: [
474
- /* @__PURE__ */ jsx8(Search2, { className: "h-12 w-12 text-muted-foreground mx-auto mb-4" }),
475
- /* @__PURE__ */ jsx8("h3", { className: "text-lg font-semibold text-foreground mb-2", children: "No articles found" }),
476
- /* @__PURE__ */ jsxs8("p", { className: "text-muted-foreground mb-4", children: [
608
+ articles.length === 0 && searchQuery ? /* @__PURE__ */ jsx9("div", { className: "text-center py-12", children: /* @__PURE__ */ jsxs9("div", { className: "max-w-md mx-auto", children: [
609
+ /* @__PURE__ */ jsx9(Search2, { className: "h-12 w-12 text-muted-foreground mx-auto mb-4" }),
610
+ /* @__PURE__ */ jsx9("h3", { className: "text-lg font-semibold text-foreground mb-2", children: "No articles found" }),
611
+ /* @__PURE__ */ jsxs9("p", { className: "text-muted-foreground mb-4", children: [
477
612
  `We couldn't find any articles matching "`,
478
613
  searchQuery,
479
614
  '". Try adjusting your search terms.'
480
615
  ] }),
481
- /* @__PURE__ */ jsx8(
616
+ /* @__PURE__ */ jsx9(
482
617
  "button",
483
618
  {
484
619
  type: "button",
@@ -487,7 +622,7 @@ function LatestArticlesSection({
487
622
  children: "Clear search"
488
623
  }
489
624
  )
490
- ] }) }) : /* @__PURE__ */ jsx8(LatestArticles, { articles, pageSize }, searchQuery)
625
+ ] }) }) : /* @__PURE__ */ jsx9(LatestArticles, { articles, pageSize }, searchQuery)
491
626
  ] }) });
492
627
  }
493
628
 
@@ -501,6 +636,15 @@ var DEFAULT_LAYOUT = [
501
636
  "latest",
502
637
  "categories"
503
638
  ];
639
+ function breadcrumbsAreEnabled(config) {
640
+ var _a;
641
+ return config.breadcrumbs !== false && ((_a = config.breadcrumbs) == null ? void 0 : _a.show) !== false;
642
+ }
643
+ function getBreadcrumbsConfig(config) {
644
+ var _a;
645
+ if (config.breadcrumbs === false) return {};
646
+ return (_a = config.breadcrumbs) != null ? _a : {};
647
+ }
504
648
 
505
649
  // src/useArticles.ts
506
650
  import { useState as useState3, useCallback, useEffect as useEffect3, useRef } from "react";
@@ -571,7 +715,7 @@ function useArticles() {
571
715
  }
572
716
 
573
717
  // src/ArticlesPage.tsx
574
- import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
718
+ import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
575
719
  function buildThemeVars(theme) {
576
720
  if (!theme) return {};
577
721
  const vars = {};
@@ -604,7 +748,7 @@ function renderSection(section, ctx, config) {
604
748
  } = ctx;
605
749
  switch (section) {
606
750
  case "hero":
607
- return /* @__PURE__ */ jsx9(
751
+ return /* @__PURE__ */ jsx10(
608
752
  ArticlesHero,
609
753
  {
610
754
  title: (_a = config.hero) == null ? void 0 : _a.title,
@@ -613,7 +757,7 @@ function renderSection(section, ctx, config) {
613
757
  "hero"
614
758
  );
615
759
  case "search":
616
- return /* @__PURE__ */ jsx9(
760
+ return /* @__PURE__ */ jsx10(
617
761
  ArticleSearchBar,
618
762
  {
619
763
  value: searchQuery,
@@ -624,7 +768,7 @@ function renderSection(section, ctx, config) {
624
768
  "search"
625
769
  );
626
770
  case "featured":
627
- return articles.length > 0 && !searchQuery ? /* @__PURE__ */ jsx9(
771
+ return articles.length > 0 && !searchQuery ? /* @__PURE__ */ jsx10(
628
772
  FeaturedArticle,
629
773
  {
630
774
  article: articles[0],
@@ -634,16 +778,16 @@ function renderSection(section, ctx, config) {
634
778
  ) : null;
635
779
  case "latest":
636
780
  if (loading && articles.length === 0) {
637
- return /* @__PURE__ */ jsx9("section", { id: "latest", className: "py-16 bg-muted/50 flex-1", children: /* @__PURE__ */ jsx9("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex items-center justify-center py-24", children: /* @__PURE__ */ jsxs9("div", { className: "text-center", children: [
638
- /* @__PURE__ */ jsx9("div", { className: "animate-spin rounded-full h-12 w-12 border-b-2 border-primary mx-auto mb-4" }),
639
- /* @__PURE__ */ jsx9("p", { className: "text-muted-foreground", children: "Loading articles..." })
781
+ return /* @__PURE__ */ jsx10("section", { id: "latest", className: "py-16 bg-muted/50 flex-1", children: /* @__PURE__ */ jsx10("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex items-center justify-center py-24", children: /* @__PURE__ */ jsxs10("div", { className: "text-center", children: [
782
+ /* @__PURE__ */ jsx10("div", { className: "animate-spin rounded-full h-12 w-12 border-b-2 border-primary mx-auto mb-4" }),
783
+ /* @__PURE__ */ jsx10("p", { className: "text-muted-foreground", children: "Loading articles..." })
640
784
  ] }) }) }, "latest");
641
785
  }
642
786
  if (error) {
643
- return /* @__PURE__ */ jsx9("section", { id: "latest", className: "py-16 bg-muted/50 flex-1", children: /* @__PURE__ */ jsx9("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex items-center justify-center", children: /* @__PURE__ */ jsxs9("div", { className: "bg-red-50 border border-red-200 rounded-lg p-6 max-w-md text-center", children: [
644
- /* @__PURE__ */ jsx9("h3", { className: "text-lg font-semibold text-red-800 mb-2", children: "Error Loading Articles" }),
645
- /* @__PURE__ */ jsx9("p", { className: "text-red-600 mb-4", children: error }),
646
- /* @__PURE__ */ jsx9(
787
+ return /* @__PURE__ */ jsx10("section", { id: "latest", className: "py-16 bg-muted/50 flex-1", children: /* @__PURE__ */ jsx10("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex items-center justify-center", children: /* @__PURE__ */ jsxs10("div", { className: "bg-red-50 border border-red-200 rounded-lg p-6 max-w-md text-center", children: [
788
+ /* @__PURE__ */ jsx10("h3", { className: "text-lg font-semibold text-red-800 mb-2", children: "Error Loading Articles" }),
789
+ /* @__PURE__ */ jsx10("p", { className: "text-red-600 mb-4", children: error }),
790
+ /* @__PURE__ */ jsx10(
647
791
  "button",
648
792
  {
649
793
  type: "button",
@@ -654,7 +798,7 @@ function renderSection(section, ctx, config) {
654
798
  )
655
799
  ] }) }) }, "latest");
656
800
  }
657
- return /* @__PURE__ */ jsx9(
801
+ return /* @__PURE__ */ jsx10(
658
802
  LatestArticlesSection,
659
803
  {
660
804
  articles: displayedArticles,
@@ -665,7 +809,7 @@ function renderSection(section, ctx, config) {
665
809
  "latest"
666
810
  );
667
811
  case "categories":
668
- return searchQuery ? null : /* @__PURE__ */ jsx9(
812
+ return searchQuery ? null : /* @__PURE__ */ jsx10(
669
813
  ArticleCategoryGrid,
670
814
  {
671
815
  categories,
@@ -689,9 +833,9 @@ function ArticlesPage({ config }) {
689
833
  const articlesWithoutFeatured = hasFeatured ? state.articles.slice(1) : state.articles;
690
834
  const displayedArticles = state.searchQuery ? state.articles : articlesWithoutFeatured;
691
835
  const ctx = __spreadProps(__spreadValues({}, state), { displayedArticles, pageSize, categoriesPageSize });
692
- return /* @__PURE__ */ jsxs9("div", { style: themeVars, children: [
836
+ return /* @__PURE__ */ jsxs10("div", { style: themeVars, children: [
693
837
  layout.map((section) => renderSection(section, ctx, config)),
694
- state.articles.length > 0 && /* @__PURE__ */ jsx9(
838
+ state.articles.length > 0 && /* @__PURE__ */ jsx10(
695
839
  CollectionPageSchema,
696
840
  {
697
841
  title: `Articles | ${config.siteName}`,
@@ -704,10 +848,11 @@ function ArticlesPage({ config }) {
704
848
  }
705
849
 
706
850
  // src/ArticleDetailHero.tsx
851
+ import { Fragment as Fragment3 } from "react";
707
852
  import Image4 from "next/image";
708
- import Link5 from "next/link";
853
+ import Link6 from "next/link";
709
854
  import { Calendar as Calendar3, Clock as Clock3, User as User2 } from "lucide-react";
710
- import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
855
+ import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
711
856
  function toSlug(cat) {
712
857
  return cat.toLowerCase().replaceAll(/\s+/g, "-").replaceAll(/[^a-z0-9-]/g, "");
713
858
  }
@@ -715,9 +860,12 @@ function ArticleDetailHero({
715
860
  article,
716
861
  categoryBasePath = "/articles/category",
717
862
  showDate = false,
718
- showAuthor = true
863
+ showAuthor = true,
864
+ authors = []
719
865
  }) {
720
- return /* @__PURE__ */ jsxs10(
866
+ const showConfiguredAuthors = showAuthor && authors.length > 0;
867
+ const showLegacyAuthor = showAuthor && authors.length === 0 && article.author.trim().length > 0;
868
+ return /* @__PURE__ */ jsxs11(
721
869
  "section",
722
870
  {
723
871
  style: {
@@ -729,7 +877,7 @@ function ArticleDetailHero({
729
877
  overflow: "hidden"
730
878
  },
731
879
  children: [
732
- /* @__PURE__ */ jsx10(
880
+ /* @__PURE__ */ jsx11(
733
881
  Image4,
734
882
  {
735
883
  src: article.featuredImage,
@@ -741,7 +889,7 @@ function ArticleDetailHero({
741
889
  priority: true
742
890
  }
743
891
  ),
744
- /* @__PURE__ */ jsx10(
892
+ /* @__PURE__ */ jsx11(
745
893
  "div",
746
894
  {
747
895
  style: {
@@ -751,7 +899,7 @@ function ArticleDetailHero({
751
899
  }
752
900
  }
753
901
  ),
754
- /* @__PURE__ */ jsxs10(
902
+ /* @__PURE__ */ jsxs11(
755
903
  "div",
756
904
  {
757
905
  style: {
@@ -765,7 +913,7 @@ function ArticleDetailHero({
765
913
  width: "100%"
766
914
  },
767
915
  children: [
768
- article.categories && article.categories.length > 0 && /* @__PURE__ */ jsx10(
916
+ article.categories && article.categories.length > 0 && /* @__PURE__ */ jsx11(
769
917
  "div",
770
918
  {
771
919
  style: {
@@ -776,15 +924,15 @@ function ArticleDetailHero({
776
924
  marginBottom: "1rem"
777
925
  },
778
926
  children: article.categories.slice(0, 4).map(
779
- (cat) => categoryBasePath ? /* @__PURE__ */ jsx10(
780
- Link5,
927
+ (cat) => categoryBasePath ? /* @__PURE__ */ jsx11(
928
+ Link6,
781
929
  {
782
930
  href: `${categoryBasePath}/${toSlug(cat)}`,
783
931
  className: "inline-block bg-white/20 text-white text-sm font-medium px-3 py-1 rounded-full hover:bg-white/30 transition-colors",
784
932
  children: cat
785
933
  },
786
934
  cat
787
- ) : /* @__PURE__ */ jsx10(
935
+ ) : /* @__PURE__ */ jsx11(
788
936
  "span",
789
937
  {
790
938
  className: "inline-block bg-white/20 text-white text-sm font-medium px-3 py-1 rounded-full",
@@ -795,8 +943,8 @@ function ArticleDetailHero({
795
943
  )
796
944
  }
797
945
  ),
798
- /* @__PURE__ */ jsx10("h1", { className: "text-4xl md:text-5xl font-bold mb-4", children: article.title }),
799
- /* @__PURE__ */ jsxs10(
946
+ /* @__PURE__ */ jsx11("h1", { className: "text-4xl md:text-5xl font-bold mb-4", children: article.title }),
947
+ /* @__PURE__ */ jsxs11(
800
948
  "div",
801
949
  {
802
950
  style: {
@@ -808,17 +956,35 @@ function ArticleDetailHero({
808
956
  color: "rgba(255,255,255,0.8)"
809
957
  },
810
958
  children: [
811
- showDate && article.date && /* @__PURE__ */ jsxs10("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
812
- /* @__PURE__ */ jsx10(Calendar3, { className: "h-4 w-4" }),
813
- /* @__PURE__ */ jsx10("span", { children: article.date })
959
+ showDate && article.date && /* @__PURE__ */ jsxs11("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
960
+ /* @__PURE__ */ jsx11(Calendar3, { className: "h-4 w-4" }),
961
+ /* @__PURE__ */ jsx11("span", { children: article.date })
962
+ ] }),
963
+ /* @__PURE__ */ jsxs11("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
964
+ /* @__PURE__ */ jsx11(Clock3, { className: "h-4 w-4" }),
965
+ /* @__PURE__ */ jsx11("span", { children: article.readTime })
814
966
  ] }),
815
- /* @__PURE__ */ jsxs10("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
816
- /* @__PURE__ */ jsx10(Clock3, { className: "h-4 w-4" }),
817
- /* @__PURE__ */ jsx10("span", { children: article.readTime })
967
+ showConfiguredAuthors && /* @__PURE__ */ jsxs11("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
968
+ /* @__PURE__ */ jsx11(User2, { className: "h-4 w-4" }),
969
+ /* @__PURE__ */ jsxs11("span", { children: [
970
+ "By",
971
+ " ",
972
+ authors.map((author, index) => /* @__PURE__ */ jsxs11(Fragment3, { children: [
973
+ index > 0 && ", ",
974
+ /* @__PURE__ */ jsx11(
975
+ Link6,
976
+ {
977
+ href: `/articles/authors/${author.slug}`,
978
+ className: "font-medium text-white underline-offset-4 hover:underline",
979
+ children: author.name
980
+ }
981
+ )
982
+ ] }, author.slug))
983
+ ] })
818
984
  ] }),
819
- showAuthor && /* @__PURE__ */ jsxs10("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
820
- /* @__PURE__ */ jsx10(User2, { className: "h-4 w-4" }),
821
- /* @__PURE__ */ jsxs10("span", { children: [
985
+ showLegacyAuthor && /* @__PURE__ */ jsxs11("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
986
+ /* @__PURE__ */ jsx11(User2, { className: "h-4 w-4" }),
987
+ /* @__PURE__ */ jsxs11("span", { children: [
822
988
  "By ",
823
989
  article.author
824
990
  ] })
@@ -836,8 +1002,8 @@ function ArticleDetailHero({
836
1002
 
837
1003
  // src/CategoryArticlesPage.tsx
838
1004
  import Image5 from "next/image";
839
- import Link6 from "next/link";
840
- import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
1005
+ import Link7 from "next/link";
1006
+ import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
841
1007
  function getCategoryDescription(config, slug, categoryName) {
842
1008
  var _a;
843
1009
  const raw = (_a = config.categoryDescriptions) == null ? void 0 : _a[slug];
@@ -845,6 +1011,40 @@ function getCategoryDescription(config, slug, categoryName) {
845
1011
  if (typeof raw === "string") return { short: raw };
846
1012
  return raw;
847
1013
  }
1014
+ function buildCategoryBreadcrumbItems(config, categoryName) {
1015
+ var _a;
1016
+ const siteUrl = config.siteUrl.replace(/\/$/, "");
1017
+ const breadcrumbConfig = getBreadcrumbsConfig(config);
1018
+ const trail = (_a = breadcrumbConfig.category) != null ? _a : ["home", "articles", "category"];
1019
+ return trail.flatMap(
1020
+ (entry) => {
1021
+ var _a2;
1022
+ return buildCategoryBreadcrumbEntry(entry, {
1023
+ categoryName,
1024
+ siteUrl,
1025
+ labels: (_a2 = breadcrumbConfig.labels) != null ? _a2 : {}
1026
+ });
1027
+ }
1028
+ );
1029
+ }
1030
+ function isCustomBreadcrumbItem(entry) {
1031
+ return typeof entry === "object" && entry !== null && "name" in entry && "url" in entry;
1032
+ }
1033
+ function resolveCustomBreadcrumbItem(item, siteUrl) {
1034
+ if (item.url.startsWith("/")) return { name: item.name, url: `${siteUrl}${item.url}` };
1035
+ return { name: item.name, url: item.url };
1036
+ }
1037
+ function buildCategoryBreadcrumbEntry(entry, context) {
1038
+ var _a, _b;
1039
+ if (isCustomBreadcrumbItem(entry)) {
1040
+ return [resolveCustomBreadcrumbItem(entry, context.siteUrl)];
1041
+ }
1042
+ if (entry === "home") return [{ name: (_a = context.labels.home) != null ? _a : "Home", url: context.siteUrl }];
1043
+ if (entry === "articles") {
1044
+ return [{ name: (_b = context.labels.articles) != null ? _b : "Articles", url: `${context.siteUrl}/articles` }];
1045
+ }
1046
+ return [{ name: context.categoryName }];
1047
+ }
848
1048
  function CategoryArticlesPage({ category, articles, config }) {
849
1049
  var _a;
850
1050
  if (articles.length === 0) return null;
@@ -852,19 +1052,18 @@ function CategoryArticlesPage({ category, articles, config }) {
852
1052
  const heroImage = articles[0].featuredImage;
853
1053
  const description = getCategoryDescription(config, category, categoryName);
854
1054
  const pageSize = (_a = config.pageSize) != null ? _a : DEFAULT_PAGE_SIZE;
855
- const siteUrl = config.siteUrl.replace(/\/$/, "");
856
- return /* @__PURE__ */ jsxs11("div", { children: [
857
- /* @__PURE__ */ jsx11(
858
- BreadcrumbSchema,
1055
+ const breadcrumbConfig = getBreadcrumbsConfig(config);
1056
+ const breadcrumbItems = buildCategoryBreadcrumbItems(config, categoryName);
1057
+ return /* @__PURE__ */ jsxs12("div", { children: [
1058
+ breadcrumbsAreEnabled(config) && /* @__PURE__ */ jsx12(
1059
+ Breadcrumb,
859
1060
  {
860
- items: [
861
- { name: "Home", url: siteUrl },
862
- { name: "Articles", url: `${siteUrl}/articles` },
863
- { name: categoryName, url: `${siteUrl}/articles/category/${category}` }
864
- ]
1061
+ items: breadcrumbItems,
1062
+ separator: breadcrumbConfig.separator,
1063
+ showSchema: breadcrumbConfig.showSchema !== false
865
1064
  }
866
1065
  ),
867
- /* @__PURE__ */ jsxs11(
1066
+ /* @__PURE__ */ jsxs12(
868
1067
  "section",
869
1068
  {
870
1069
  style: {
@@ -876,7 +1075,7 @@ function CategoryArticlesPage({ category, articles, config }) {
876
1075
  overflow: "hidden"
877
1076
  },
878
1077
  children: [
879
- /* @__PURE__ */ jsx11(
1078
+ /* @__PURE__ */ jsx12(
880
1079
  Image5,
881
1080
  {
882
1081
  src: heroImage,
@@ -887,8 +1086,8 @@ function CategoryArticlesPage({ category, articles, config }) {
887
1086
  priority: true
888
1087
  }
889
1088
  ),
890
- /* @__PURE__ */ jsx11("div", { style: { position: "absolute", inset: 0, backgroundColor: "rgba(0,0,0,0.6)" } }),
891
- /* @__PURE__ */ jsxs11(
1089
+ /* @__PURE__ */ jsx12("div", { style: { position: "absolute", inset: 0, backgroundColor: "rgba(0,0,0,0.6)" } }),
1090
+ /* @__PURE__ */ jsxs12(
892
1091
  "div",
893
1092
  {
894
1093
  style: {
@@ -899,10 +1098,10 @@ function CategoryArticlesPage({ category, articles, config }) {
899
1098
  padding: "0 1rem"
900
1099
  },
901
1100
  children: [
902
- /* @__PURE__ */ jsx11("p", { className: "text-sm font-semibold uppercase tracking-widest mb-3 opacity-80", children: "Category" }),
903
- /* @__PURE__ */ jsx11("h1", { className: "text-4xl md:text-5xl font-bold mb-3", children: categoryName }),
904
- description.long && /* @__PURE__ */ jsx11("p", { className: "text-lg opacity-90 max-w-2xl mx-auto mt-2", children: description.long }),
905
- /* @__PURE__ */ jsxs11("p", { className: "text-lg opacity-70 mt-2", children: [
1101
+ /* @__PURE__ */ jsx12("p", { className: "text-sm font-semibold uppercase tracking-widest mb-3 opacity-80", children: "Category" }),
1102
+ /* @__PURE__ */ jsx12("h1", { className: "text-4xl md:text-5xl font-bold mb-3", children: categoryName }),
1103
+ description.long && /* @__PURE__ */ jsx12("p", { className: "text-lg opacity-90 max-w-2xl mx-auto mt-2", children: description.long }),
1104
+ /* @__PURE__ */ jsxs12("p", { className: "text-lg opacity-70 mt-2", children: [
906
1105
  articles.length,
907
1106
  " article",
908
1107
  articles.length === 1 ? "" : "s"
@@ -913,20 +1112,178 @@ function CategoryArticlesPage({ category, articles, config }) {
913
1112
  ]
914
1113
  }
915
1114
  ),
916
- /* @__PURE__ */ jsx11("section", { className: "py-16 bg-muted/50 flex-1", children: /* @__PURE__ */ jsxs11("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: [
917
- /* @__PURE__ */ jsxs11("div", { className: "mb-8 flex items-center justify-between", children: [
918
- /* @__PURE__ */ jsx11(Link6, { href: "/articles", className: "text-sm text-primary hover:underline", children: "\u2190 All Articles" }),
919
- /* @__PURE__ */ jsx11("p", { className: "text-sm text-muted-foreground", children: description.short })
1115
+ /* @__PURE__ */ jsx12("section", { className: "py-16 bg-muted/50 flex-1", children: /* @__PURE__ */ jsxs12("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: [
1116
+ /* @__PURE__ */ jsxs12("div", { className: "mb-8 flex items-center justify-between", children: [
1117
+ /* @__PURE__ */ jsx12(Link7, { href: "/articles", className: "text-sm text-primary hover:underline", children: "\u2190 All Articles" }),
1118
+ /* @__PURE__ */ jsx12("p", { className: "text-sm text-muted-foreground", children: description.short })
920
1119
  ] }),
921
- /* @__PURE__ */ jsx11(LatestArticles, { articles, pageSize })
1120
+ /* @__PURE__ */ jsx12(LatestArticles, { articles, pageSize })
922
1121
  ] }) })
923
1122
  ] });
924
1123
  }
925
1124
 
1125
+ // src/AuthorArticlesPage.tsx
1126
+ import Link8 from "next/link";
1127
+ import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
1128
+ function getPersonSchema(author, config, articleCount) {
1129
+ var _a, _b;
1130
+ return __spreadProps(__spreadValues(__spreadValues({
1131
+ "@context": "https://schema.org",
1132
+ "@type": "Person",
1133
+ name: author.name,
1134
+ description: author.bio,
1135
+ url: (_a = author.url) != null ? _a : getAuthorUrl(author)
1136
+ }, getAuthorAvatar(author, config) && { image: getAuthorAvatar(author, config) }), getAuthorSameAs(author).length > 0 && { sameAs: getAuthorSameAs(author) }), {
1137
+ knowsAbout: config.siteName,
1138
+ mainEntityOfPage: (_b = author.url) != null ? _b : `${config.siteUrl.replace(/\/$/, "")}/articles/authors/${author.slug}`,
1139
+ interactionStatistic: {
1140
+ "@type": "InteractionCounter",
1141
+ interactionType: "https://schema.org/WriteAction",
1142
+ userInteractionCount: articleCount
1143
+ }
1144
+ });
1145
+ }
1146
+ function AuthorArticlesPage({ author, articles, config }) {
1147
+ var _a;
1148
+ const pageSize = (_a = config.pageSize) != null ? _a : DEFAULT_PAGE_SIZE;
1149
+ return /* @__PURE__ */ jsxs13("div", { children: [
1150
+ /* @__PURE__ */ jsx13(
1151
+ "script",
1152
+ {
1153
+ type: "application/ld+json",
1154
+ dangerouslySetInnerHTML: {
1155
+ __html: JSON.stringify(getPersonSchema(author, config, articles.length))
1156
+ }
1157
+ }
1158
+ ),
1159
+ /* @__PURE__ */ jsx13("section", { className: "bg-background py-16", children: /* @__PURE__ */ jsxs13("div", { className: "mx-auto max-w-7xl px-4 sm:px-6 lg:px-8", children: [
1160
+ /* @__PURE__ */ jsxs13("div", { className: "mb-8 flex items-center justify-between gap-4", children: [
1161
+ /* @__PURE__ */ jsx13(Link8, { href: "/articles", className: "text-sm text-primary hover:underline", children: "All Articles" }),
1162
+ /* @__PURE__ */ jsxs13("p", { className: "text-sm text-muted-foreground", children: [
1163
+ "Articles by ",
1164
+ author.name
1165
+ ] })
1166
+ ] }),
1167
+ /* @__PURE__ */ jsx13(LatestArticles, { articles, pageSize })
1168
+ ] }) })
1169
+ ] });
1170
+ }
1171
+
1172
+ // src/AuthorCard.tsx
1173
+ import Image6 from "next/image";
1174
+ import Link9 from "next/link";
1175
+ import {
1176
+ Facebook,
1177
+ Github,
1178
+ Globe,
1179
+ Instagram,
1180
+ Linkedin,
1181
+ Mail,
1182
+ MessageCircle,
1183
+ Twitter,
1184
+ Youtube
1185
+ } from "lucide-react";
1186
+ import { jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
1187
+ function getInitials(name) {
1188
+ return name.split(" ").filter(Boolean).slice(0, 2).map((part) => part.charAt(0).toUpperCase()).join("");
1189
+ }
1190
+ function AuthorCard({
1191
+ author,
1192
+ linkToPage = true,
1193
+ showBio = false,
1194
+ showSocial = false
1195
+ }) {
1196
+ const avatar = getAuthorAvatar(author);
1197
+ const name = linkToPage ? /* @__PURE__ */ jsx14(Link9, { href: getAuthorUrl(author), className: "font-medium text-foreground hover:text-primary", children: author.name }) : /* @__PURE__ */ jsx14("span", { className: "font-medium text-foreground", children: author.name });
1198
+ return /* @__PURE__ */ jsxs14("div", { className: "flex items-start gap-3 rounded-lg border border-border bg-card p-4 text-card-foreground", children: [
1199
+ avatar ? /* @__PURE__ */ jsx14(
1200
+ Image6,
1201
+ {
1202
+ src: avatar,
1203
+ alt: author.name,
1204
+ width: 48,
1205
+ height: 48,
1206
+ className: "h-12 w-12 rounded-full object-cover"
1207
+ }
1208
+ ) : /* @__PURE__ */ jsx14("div", { className: "flex h-12 w-12 shrink-0 items-center justify-center rounded-full bg-muted text-sm font-semibold text-muted-foreground", children: getInitials(author.name) }),
1209
+ /* @__PURE__ */ jsxs14("div", { className: "min-w-0 flex-1", children: [
1210
+ name,
1211
+ showBio && author.bio && /* @__PURE__ */ jsx14("p", { className: "mt-1 line-clamp-2 text-sm text-muted-foreground", children: author.bio }),
1212
+ showSocial && /* @__PURE__ */ jsx14(AuthorSocialLinks, { author })
1213
+ ] })
1214
+ ] });
1215
+ }
1216
+ var SOCIAL_ICONS = {
1217
+ Website: Globe,
1218
+ Facebook,
1219
+ Twitter,
1220
+ X: Twitter,
1221
+ LinkedIn: Linkedin,
1222
+ Instagram,
1223
+ YouTube: Youtube,
1224
+ GitHub: Github,
1225
+ Newsletter: Mail
1226
+ };
1227
+ function getSocialIcon(label) {
1228
+ var _a;
1229
+ return (_a = SOCIAL_ICONS[label]) != null ? _a : MessageCircle;
1230
+ }
1231
+ function AuthorSocialLinks({ author }) {
1232
+ const links = getAuthorSocialLinks(author);
1233
+ if (links.length === 0) return null;
1234
+ return /* @__PURE__ */ jsx14("div", { className: "mt-3 flex items-center gap-2", children: links.map(({ href, label }) => {
1235
+ const Icon = getSocialIcon(label);
1236
+ return /* @__PURE__ */ jsx14(
1237
+ Link9,
1238
+ {
1239
+ href,
1240
+ className: "inline-flex h-8 w-8 items-center justify-center rounded-md border border-border text-muted-foreground hover:bg-accent hover:text-accent-foreground",
1241
+ "aria-label": `${author.name} on ${label}`,
1242
+ children: /* @__PURE__ */ jsx14(Icon, { className: "h-4 w-4" })
1243
+ },
1244
+ `${label}-${href}`
1245
+ );
1246
+ }) });
1247
+ }
1248
+
1249
+ // src/AuthorDetailHero.tsx
1250
+ import Image7 from "next/image";
1251
+ import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
1252
+ function getInitials2(name) {
1253
+ return name.split(" ").filter(Boolean).slice(0, 2).map((part) => part.charAt(0).toUpperCase()).join("");
1254
+ }
1255
+ function AuthorDetailHero({ author, articleCount }) {
1256
+ const avatar = getAuthorAvatar(author);
1257
+ return /* @__PURE__ */ jsx15("section", { className: "bg-muted/40 py-16", children: /* @__PURE__ */ jsxs15("div", { className: "mx-auto flex max-w-4xl flex-col items-center gap-6 px-4 text-center sm:px-6 lg:px-8", children: [
1258
+ avatar ? /* @__PURE__ */ jsx15(
1259
+ Image7,
1260
+ {
1261
+ src: avatar,
1262
+ alt: author.name,
1263
+ width: 120,
1264
+ height: 120,
1265
+ className: "h-28 w-28 rounded-full object-cover",
1266
+ priority: true
1267
+ }
1268
+ ) : /* @__PURE__ */ jsx15("div", { className: "flex h-28 w-28 items-center justify-center rounded-full bg-card text-3xl font-semibold text-muted-foreground shadow-sm", children: getInitials2(author.name) }),
1269
+ /* @__PURE__ */ jsxs15("div", { children: [
1270
+ /* @__PURE__ */ jsx15("p", { className: "mb-3 text-sm font-semibold uppercase tracking-widest text-muted-foreground", children: "Author" }),
1271
+ /* @__PURE__ */ jsx15("h1", { className: "text-4xl font-bold text-foreground md:text-5xl", children: author.name }),
1272
+ /* @__PURE__ */ jsx15("p", { className: "mx-auto mt-4 max-w-2xl text-lg text-muted-foreground", children: author.bio }),
1273
+ typeof articleCount === "number" && /* @__PURE__ */ jsxs15("p", { className: "mt-3 text-sm text-muted-foreground", children: [
1274
+ articleCount,
1275
+ " article",
1276
+ articleCount === 1 ? "" : "s"
1277
+ ] })
1278
+ ] }),
1279
+ /* @__PURE__ */ jsx15(AuthorSocialLinks, { author })
1280
+ ] }) });
1281
+ }
1282
+
926
1283
  // src/ArticleSocialShare.tsx
927
1284
  import { useState as useState4 } from "react";
928
- import { Share2, Copy, Check, Mail, MessageCircle, Users, FileText } from "lucide-react";
929
- import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
1285
+ import { Share2, Copy, Check, Mail as Mail2, MessageCircle as MessageCircle2, Users, FileText } from "lucide-react";
1286
+ import { jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
930
1287
  function ArticleSocialShare({ title, url, excerpt, shareMessage }) {
931
1288
  const [copied, setCopied] = useState4(false);
932
1289
  const encodedTitle = encodeURIComponent(title);
@@ -953,84 +1310,84 @@ function ArticleSocialShare({ title, url, excerpt, shareMessage }) {
953
1310
  globalThis.open(shareUrl, "_blank", "width=600,height=400,scrollbars=yes,resizable=yes");
954
1311
  };
955
1312
  const btnClass = "inline-flex items-center gap-2 px-3 py-1.5 text-sm rounded-md border border-border bg-background text-foreground hover:bg-primary/10 hover:border-primary hover:text-primary transition-colors cursor-pointer";
956
- return /* @__PURE__ */ jsxs12("div", { className: "border-t border-border pt-8 mt-8", children: [
957
- /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2 mb-4", children: [
958
- /* @__PURE__ */ jsx12(Share2, { className: "h-5 w-5 text-muted-foreground" }),
959
- /* @__PURE__ */ jsx12("h3", { className: "text-lg font-semibold text-foreground", children: "Share this article" })
1313
+ return /* @__PURE__ */ jsxs16("div", { className: "border-t border-border pt-8 mt-8", children: [
1314
+ /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2 mb-4", children: [
1315
+ /* @__PURE__ */ jsx16(Share2, { className: "h-5 w-5 text-muted-foreground" }),
1316
+ /* @__PURE__ */ jsx16("h3", { className: "text-lg font-semibold text-foreground", children: "Share this article" })
960
1317
  ] }),
961
- /* @__PURE__ */ jsxs12("div", { className: "flex flex-wrap gap-2", children: [
962
- /* @__PURE__ */ jsxs12("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.linkedin), children: [
963
- /* @__PURE__ */ jsx12(Users, { className: "h-4 w-4" }),
1318
+ /* @__PURE__ */ jsxs16("div", { className: "flex flex-wrap gap-2", children: [
1319
+ /* @__PURE__ */ jsxs16("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.linkedin), children: [
1320
+ /* @__PURE__ */ jsx16(Users, { className: "h-4 w-4" }),
964
1321
  "LinkedIn"
965
1322
  ] }),
966
- /* @__PURE__ */ jsxs12("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.facebook), children: [
967
- /* @__PURE__ */ jsx12("span", { className: "text-xs font-bold", children: "f" }),
1323
+ /* @__PURE__ */ jsxs16("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.facebook), children: [
1324
+ /* @__PURE__ */ jsx16("span", { className: "text-xs font-bold", children: "f" }),
968
1325
  " Facebook"
969
1326
  ] }),
970
- /* @__PURE__ */ jsxs12("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.twitter), children: [
971
- /* @__PURE__ */ jsx12(MessageCircle, { className: "h-4 w-4" }),
1327
+ /* @__PURE__ */ jsxs16("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.twitter), children: [
1328
+ /* @__PURE__ */ jsx16(MessageCircle2, { className: "h-4 w-4" }),
972
1329
  "Twitter"
973
1330
  ] }),
974
- /* @__PURE__ */ jsxs12("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.reddit), children: [
975
- /* @__PURE__ */ jsx12(FileText, { className: "h-4 w-4" }),
1331
+ /* @__PURE__ */ jsxs16("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.reddit), children: [
1332
+ /* @__PURE__ */ jsx16(FileText, { className: "h-4 w-4" }),
976
1333
  "Reddit"
977
1334
  ] }),
978
- /* @__PURE__ */ jsxs12("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.whatsapp), children: [
979
- /* @__PURE__ */ jsx12(MessageCircle, { className: "h-4 w-4" }),
1335
+ /* @__PURE__ */ jsxs16("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.whatsapp), children: [
1336
+ /* @__PURE__ */ jsx16(MessageCircle2, { className: "h-4 w-4" }),
980
1337
  "WhatsApp"
981
1338
  ] }),
982
- /* @__PURE__ */ jsxs12("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.telegram), children: [
983
- /* @__PURE__ */ jsx12(MessageCircle, { className: "h-4 w-4" }),
1339
+ /* @__PURE__ */ jsxs16("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.telegram), children: [
1340
+ /* @__PURE__ */ jsx16(MessageCircle2, { className: "h-4 w-4" }),
984
1341
  "Telegram"
985
1342
  ] }),
986
- /* @__PURE__ */ jsxs12("a", { className: btnClass, href: shareLinks.email, children: [
987
- /* @__PURE__ */ jsx12(Mail, { className: "h-4 w-4" }),
1343
+ /* @__PURE__ */ jsxs16("a", { className: btnClass, href: shareLinks.email, children: [
1344
+ /* @__PURE__ */ jsx16(Mail2, { className: "h-4 w-4" }),
988
1345
  "Email"
989
1346
  ] }),
990
- /* @__PURE__ */ jsxs12("button", { className: btnClass, onClick: copyToClipboard, children: [
991
- copied ? /* @__PURE__ */ jsx12(Check, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx12(Copy, { className: "h-4 w-4" }),
1347
+ /* @__PURE__ */ jsxs16("button", { className: btnClass, onClick: copyToClipboard, children: [
1348
+ copied ? /* @__PURE__ */ jsx16(Check, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx16(Copy, { className: "h-4 w-4" }),
992
1349
  copied ? "Copied!" : "Copy Link"
993
1350
  ] })
994
1351
  ] }),
995
- shareMessage && /* @__PURE__ */ jsx12("p", { className: "text-sm text-muted-foreground mt-3", children: shareMessage })
1352
+ shareMessage && /* @__PURE__ */ jsx16("p", { className: "text-sm text-muted-foreground mt-3", children: shareMessage })
996
1353
  ] });
997
1354
  }
998
1355
 
999
1356
  // src/ArticleNavigation.tsx
1000
- import Link7 from "next/link";
1357
+ import Link10 from "next/link";
1001
1358
  import { ChevronLeft, ChevronRight } from "lucide-react";
1002
- import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
1359
+ import { jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
1003
1360
  function truncateTitle(title, maxLength = 60) {
1004
1361
  return title.length > maxLength ? `${title.substring(0, maxLength)}...` : title;
1005
1362
  }
1006
1363
  function ArticleNavigation({ previous, next, basePath }) {
1007
1364
  if (!previous && !next) return null;
1008
- return /* @__PURE__ */ jsx13("nav", { className: "mt-12 pt-8 border-t border-border", "aria-label": "Article navigation", children: /* @__PURE__ */ jsxs13("div", { className: "flex justify-between gap-4", children: [
1009
- /* @__PURE__ */ jsx13("div", { className: "flex-1 min-w-0", children: previous && /* @__PURE__ */ jsxs13(
1010
- Link7,
1365
+ return /* @__PURE__ */ jsx17("nav", { className: "mt-12 pt-8 border-t border-border", "aria-label": "Article navigation", children: /* @__PURE__ */ jsxs17("div", { className: "flex justify-between gap-4", children: [
1366
+ /* @__PURE__ */ jsx17("div", { className: "flex-1 min-w-0", children: previous && /* @__PURE__ */ jsxs17(
1367
+ Link10,
1011
1368
  {
1012
1369
  href: `${basePath}/${previous.slug}`,
1013
1370
  className: "group flex items-center gap-3 p-4 rounded-lg border border-border hover:border-primary/20 hover:bg-muted/50 transition-colors",
1014
1371
  children: [
1015
- /* @__PURE__ */ jsx13(ChevronLeft, { className: "h-5 w-5 text-muted-foreground group-hover:text-primary shrink-0" }),
1016
- /* @__PURE__ */ jsxs13("div", { className: "min-w-0 flex-1", children: [
1017
- /* @__PURE__ */ jsx13("div", { className: "text-sm text-muted-foreground mb-1", children: "Previous Article" }),
1018
- /* @__PURE__ */ jsx13("div", { className: "font-medium text-foreground truncate", title: previous.title, children: truncateTitle(previous.title) })
1372
+ /* @__PURE__ */ jsx17(ChevronLeft, { className: "h-5 w-5 text-muted-foreground group-hover:text-primary shrink-0" }),
1373
+ /* @__PURE__ */ jsxs17("div", { className: "min-w-0 flex-1", children: [
1374
+ /* @__PURE__ */ jsx17("div", { className: "text-sm text-muted-foreground mb-1", children: "Previous Article" }),
1375
+ /* @__PURE__ */ jsx17("div", { className: "font-medium text-foreground truncate", title: previous.title, children: truncateTitle(previous.title) })
1019
1376
  ] })
1020
1377
  ]
1021
1378
  }
1022
1379
  ) }),
1023
- /* @__PURE__ */ jsx13("div", { className: "flex-1 min-w-0", children: next && /* @__PURE__ */ jsxs13(
1024
- Link7,
1380
+ /* @__PURE__ */ jsx17("div", { className: "flex-1 min-w-0", children: next && /* @__PURE__ */ jsxs17(
1381
+ Link10,
1025
1382
  {
1026
1383
  href: `${basePath}/${next.slug}`,
1027
1384
  className: "group flex items-center justify-end gap-3 p-4 rounded-lg border border-border hover:border-primary/20 hover:bg-muted/50 transition-colors",
1028
1385
  children: [
1029
- /* @__PURE__ */ jsxs13("div", { className: "min-w-0 flex-1 text-right", children: [
1030
- /* @__PURE__ */ jsx13("div", { className: "text-sm text-muted-foreground mb-1", children: "Next Article" }),
1031
- /* @__PURE__ */ jsx13("div", { className: "font-medium text-foreground truncate", title: next.title, children: truncateTitle(next.title) })
1386
+ /* @__PURE__ */ jsxs17("div", { className: "min-w-0 flex-1 text-right", children: [
1387
+ /* @__PURE__ */ jsx17("div", { className: "text-sm text-muted-foreground mb-1", children: "Next Article" }),
1388
+ /* @__PURE__ */ jsx17("div", { className: "font-medium text-foreground truncate", title: next.title, children: truncateTitle(next.title) })
1032
1389
  ] }),
1033
- /* @__PURE__ */ jsx13(ChevronRight, { className: "h-5 w-5 text-muted-foreground group-hover:text-primary shrink-0" })
1390
+ /* @__PURE__ */ jsx17(ChevronRight, { className: "h-5 w-5 text-muted-foreground group-hover:text-primary shrink-0" })
1034
1391
  ]
1035
1392
  }
1036
1393
  ) })
@@ -1038,9 +1395,9 @@ function ArticleNavigation({ previous, next, basePath }) {
1038
1395
  }
1039
1396
 
1040
1397
  // src/ArticleBackLink.tsx
1041
- import Link8 from "next/link";
1398
+ import Link11 from "next/link";
1042
1399
  import { ArrowLeft } from "lucide-react";
1043
- import { jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
1400
+ import { jsx as jsx18, jsxs as jsxs18 } from "react/jsx-runtime";
1044
1401
  function ArticleBackLink({
1045
1402
  config,
1046
1403
  href = "/articles",
@@ -1048,13 +1405,13 @@ function ArticleBackLink({
1048
1405
  className
1049
1406
  }) {
1050
1407
  if (config.showBackToArticles === false) return null;
1051
- return /* @__PURE__ */ jsxs14(
1052
- Link8,
1408
+ return /* @__PURE__ */ jsxs18(
1409
+ Link11,
1053
1410
  {
1054
1411
  href,
1055
1412
  className: className != null ? className : "inline-flex items-center gap-2 mb-6 -ml-3 px-3 py-2 rounded-md text-sm font-medium text-muted-foreground hover:text-foreground hover:bg-muted/50 transition-colors",
1056
1413
  children: [
1057
- /* @__PURE__ */ jsx14(ArrowLeft, { className: "h-4 w-4" }),
1414
+ /* @__PURE__ */ jsx18(ArrowLeft, { className: "h-4 w-4" }),
1058
1415
  label
1059
1416
  ]
1060
1417
  }
@@ -1062,17 +1419,17 @@ function ArticleBackLink({
1062
1419
  }
1063
1420
 
1064
1421
  // src/ArticleTOC.tsx
1065
- import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
1422
+ import { jsx as jsx19, jsxs as jsxs19 } from "react/jsx-runtime";
1066
1423
  function ArticleTOC({ toc, className }) {
1067
1424
  if (!toc.length) return null;
1068
- return /* @__PURE__ */ jsxs15(
1425
+ return /* @__PURE__ */ jsxs19(
1069
1426
  "nav",
1070
1427
  {
1071
1428
  "aria-label": "Table of contents",
1072
1429
  className: `mb-8 rounded-lg border border-border bg-muted/40 px-6 py-4 ${className != null ? className : ""}`,
1073
1430
  children: [
1074
- /* @__PURE__ */ jsx15("p", { className: "mb-3 text-sm font-semibold uppercase tracking-wide text-muted-foreground", children: "On this page" }),
1075
- /* @__PURE__ */ jsx15("ul", { className: "space-y-1 text-sm", children: toc.map((item) => /* @__PURE__ */ jsx15("li", { style: { paddingLeft: `${Math.max(0, item.depth - 2) * 1}rem` }, children: /* @__PURE__ */ jsx15(
1431
+ /* @__PURE__ */ jsx19("p", { className: "mb-3 text-sm font-semibold uppercase tracking-wide text-muted-foreground", children: "On this page" }),
1432
+ /* @__PURE__ */ jsx19("ul", { className: "space-y-1 text-sm", children: toc.map((item) => /* @__PURE__ */ jsx19("li", { style: { paddingLeft: `${Math.max(0, item.depth - 2) * 1}rem` }, children: /* @__PURE__ */ jsx19(
1076
1433
  "a",
1077
1434
  {
1078
1435
  href: `#${item.id}`,
@@ -1088,7 +1445,7 @@ function ArticleTOC({ toc, className }) {
1088
1445
  // src/ScrollToTop.tsx
1089
1446
  import { useEffect as useEffect4, useState as useState5 } from "react";
1090
1447
  import { ArrowUp } from "lucide-react";
1091
- import { jsx as jsx16 } from "react/jsx-runtime";
1448
+ import { jsx as jsx20 } from "react/jsx-runtime";
1092
1449
  function ScrollToTop() {
1093
1450
  const [visible, setVisible] = useState5(false);
1094
1451
  useEffect4(() => {
@@ -1097,13 +1454,13 @@ function ScrollToTop() {
1097
1454
  return () => globalThis.removeEventListener("scroll", onScroll);
1098
1455
  }, []);
1099
1456
  if (!visible) return null;
1100
- return /* @__PURE__ */ jsx16(
1457
+ return /* @__PURE__ */ jsx20(
1101
1458
  "button",
1102
1459
  {
1103
1460
  "aria-label": "Scroll to top",
1104
1461
  onClick: () => globalThis.scrollTo({ top: 0, behavior: "smooth" }),
1105
1462
  className: "fixed bottom-8 right-8 z-50 rounded-full bg-primary p-2 shadow-md text-primary-foreground hover:bg-primary/90 transition-colors",
1106
- children: /* @__PURE__ */ jsx16(ArrowUp, { className: "h-5 w-5" })
1463
+ children: /* @__PURE__ */ jsx20(ArrowUp, { className: "h-5 w-5" })
1107
1464
  }
1108
1465
  );
1109
1466
  }
@@ -1114,7 +1471,7 @@ import { useCallback as useCallback2, useEffect as useEffect5, useState as useSt
1114
1471
 
1115
1472
  // src/CommentForm.tsx
1116
1473
  import { useState as useState6 } from "react";
1117
- import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
1474
+ import { jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
1118
1475
  var MAX_LENGTH = 2e3;
1119
1476
  var WARN_THRESHOLD = 1800;
1120
1477
  function submitLabel(submitting, parentId) {
@@ -1153,8 +1510,8 @@ function CommentForm({ articleSlug, parentId, onSuccess, onCancel }) {
1153
1510
  }
1154
1511
  });
1155
1512
  }
1156
- return /* @__PURE__ */ jsxs16("form", { onSubmit: handleSubmit, className: "space-y-2", children: [
1157
- /* @__PURE__ */ jsx17(
1513
+ return /* @__PURE__ */ jsxs20("form", { onSubmit: handleSubmit, className: "space-y-2", children: [
1514
+ /* @__PURE__ */ jsx21(
1158
1515
  "textarea",
1159
1516
  {
1160
1517
  value: body,
@@ -1167,13 +1524,13 @@ function CommentForm({ articleSlug, parentId, onSuccess, onCancel }) {
1167
1524
  "aria-label": parentId ? "Reply text" : "Comment text"
1168
1525
  }
1169
1526
  ),
1170
- remaining <= MAX_LENGTH - WARN_THRESHOLD && /* @__PURE__ */ jsxs16("p", { className: `text-xs ${remaining < 0 ? "text-destructive" : "text-muted-foreground"}`, children: [
1527
+ remaining <= MAX_LENGTH - WARN_THRESHOLD && /* @__PURE__ */ jsxs20("p", { className: `text-xs ${remaining < 0 ? "text-destructive" : "text-muted-foreground"}`, children: [
1171
1528
  remaining,
1172
1529
  " characters remaining"
1173
1530
  ] }),
1174
- error && /* @__PURE__ */ jsx17("p", { className: "text-xs text-destructive", children: error }),
1175
- /* @__PURE__ */ jsxs16("div", { className: "flex gap-2", children: [
1176
- /* @__PURE__ */ jsx17(
1531
+ error && /* @__PURE__ */ jsx21("p", { className: "text-xs text-destructive", children: error }),
1532
+ /* @__PURE__ */ jsxs20("div", { className: "flex gap-2", children: [
1533
+ /* @__PURE__ */ jsx21(
1177
1534
  "button",
1178
1535
  {
1179
1536
  type: "submit",
@@ -1182,7 +1539,7 @@ function CommentForm({ articleSlug, parentId, onSuccess, onCancel }) {
1182
1539
  children: submitLabel(submitting, parentId)
1183
1540
  }
1184
1541
  ),
1185
- onCancel && /* @__PURE__ */ jsx17(
1542
+ onCancel && /* @__PURE__ */ jsx21(
1186
1543
  "button",
1187
1544
  {
1188
1545
  type: "button",
@@ -1197,7 +1554,7 @@ function CommentForm({ articleSlug, parentId, onSuccess, onCancel }) {
1197
1554
 
1198
1555
  // src/CommentItem.tsx
1199
1556
  import { useState as useState7 } from "react";
1200
- import { Fragment as Fragment2, jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
1557
+ import { Fragment as Fragment4, jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
1201
1558
  function relativeTime(iso) {
1202
1559
  const diff = Date.now() - new Date(iso).getTime();
1203
1560
  const minutes = Math.floor(diff / 6e4);
@@ -1235,15 +1592,15 @@ function CommentItem({
1235
1592
  }
1236
1593
  });
1237
1594
  }
1238
- return /* @__PURE__ */ jsxs17("div", { className: `${isReply ? "ml-8 border-l-2 border-border pl-4" : ""}`, children: [
1239
- /* @__PURE__ */ jsx18("div", { className: "rounded-lg bg-muted/40 p-3 space-y-1", children: comment.isDeleted ? /* @__PURE__ */ jsx18("p", { className: "text-sm italic text-muted-foreground", children: "Comment removed" }) : /* @__PURE__ */ jsxs17(Fragment2, { children: [
1240
- /* @__PURE__ */ jsxs17("div", { className: "flex items-center justify-between gap-2", children: [
1241
- /* @__PURE__ */ jsx18("span", { className: "text-sm font-medium text-foreground", children: comment.authorName }),
1242
- /* @__PURE__ */ jsx18("span", { className: "text-xs text-muted-foreground", children: relativeTime(comment.createdAt) })
1595
+ return /* @__PURE__ */ jsxs21("div", { className: `${isReply ? "ml-8 border-l-2 border-border pl-4" : ""}`, children: [
1596
+ /* @__PURE__ */ jsx22("div", { className: "rounded-lg bg-muted/40 p-3 space-y-1", children: comment.isDeleted ? /* @__PURE__ */ jsx22("p", { className: "text-sm italic text-muted-foreground", children: "Comment removed" }) : /* @__PURE__ */ jsxs21(Fragment4, { children: [
1597
+ /* @__PURE__ */ jsxs21("div", { className: "flex items-center justify-between gap-2", children: [
1598
+ /* @__PURE__ */ jsx22("span", { className: "text-sm font-medium text-foreground", children: comment.authorName }),
1599
+ /* @__PURE__ */ jsx22("span", { className: "text-xs text-muted-foreground", children: relativeTime(comment.createdAt) })
1243
1600
  ] }),
1244
- /* @__PURE__ */ jsx18("p", { className: "text-sm text-foreground whitespace-pre-wrap break-words", children: comment.body }),
1245
- /* @__PURE__ */ jsxs17("div", { className: "flex gap-3 pt-1", children: [
1246
- canReply && /* @__PURE__ */ jsx18(
1601
+ /* @__PURE__ */ jsx22("p", { className: "text-sm text-foreground whitespace-pre-wrap break-words", children: comment.body }),
1602
+ /* @__PURE__ */ jsxs21("div", { className: "flex gap-3 pt-1", children: [
1603
+ canReply && /* @__PURE__ */ jsx22(
1247
1604
  "button",
1248
1605
  {
1249
1606
  onClick: () => setShowReplyForm((v) => !v),
@@ -1251,7 +1608,7 @@ function CommentItem({
1251
1608
  children: showReplyForm ? "Cancel" : "Reply"
1252
1609
  }
1253
1610
  ),
1254
- canDelete && /* @__PURE__ */ jsx18(
1611
+ canDelete && /* @__PURE__ */ jsx22(
1255
1612
  "button",
1256
1613
  {
1257
1614
  onClick: handleDelete,
@@ -1262,7 +1619,7 @@ function CommentItem({
1262
1619
  )
1263
1620
  ] })
1264
1621
  ] }) }),
1265
- showReplyForm && /* @__PURE__ */ jsx18("div", { className: "mt-2 ml-2", children: /* @__PURE__ */ jsx18(
1622
+ showReplyForm && /* @__PURE__ */ jsx22("div", { className: "mt-2 ml-2", children: /* @__PURE__ */ jsx22(
1266
1623
  CommentForm,
1267
1624
  {
1268
1625
  articleSlug,
@@ -1274,7 +1631,7 @@ function CommentItem({
1274
1631
  onCancel: () => setShowReplyForm(false)
1275
1632
  }
1276
1633
  ) }),
1277
- replies.length > 0 && /* @__PURE__ */ jsx18("div", { className: "mt-2 space-y-2", children: replies.map((reply) => /* @__PURE__ */ jsx18(
1634
+ replies.length > 0 && /* @__PURE__ */ jsx22("div", { className: "mt-2 space-y-2", children: replies.map((reply) => /* @__PURE__ */ jsx22(
1278
1635
  CommentItem,
1279
1636
  {
1280
1637
  comment: __spreadProps(__spreadValues({}, reply), { replies: [] }),
@@ -1289,7 +1646,7 @@ function CommentItem({
1289
1646
  }
1290
1647
 
1291
1648
  // src/CommentThread.tsx
1292
- import { jsx as jsx19 } from "react/jsx-runtime";
1649
+ import { jsx as jsx23 } from "react/jsx-runtime";
1293
1650
  function CommentThread({
1294
1651
  comments,
1295
1652
  articleSlug,
@@ -1297,9 +1654,9 @@ function CommentThread({
1297
1654
  onRefresh
1298
1655
  }) {
1299
1656
  if (comments.length === 0) {
1300
- return /* @__PURE__ */ jsx19("p", { className: "text-sm text-muted-foreground text-center py-6", children: "No comments yet. Be the first to share your thoughts." });
1657
+ return /* @__PURE__ */ jsx23("p", { className: "text-sm text-muted-foreground text-center py-6", children: "No comments yet. Be the first to share your thoughts." });
1301
1658
  }
1302
- return /* @__PURE__ */ jsx19("div", { className: "space-y-4", children: comments.map((comment) => /* @__PURE__ */ jsx19(
1659
+ return /* @__PURE__ */ jsx23("div", { className: "space-y-4", children: comments.map((comment) => /* @__PURE__ */ jsx23(
1303
1660
  CommentItem,
1304
1661
  {
1305
1662
  comment,
@@ -1312,7 +1669,7 @@ function CommentThread({
1312
1669
  }
1313
1670
 
1314
1671
  // src/CommentsSection.tsx
1315
- import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
1672
+ import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
1316
1673
  function CommentsSection({ articleSlug, config }) {
1317
1674
  var _a, _b, _c, _d, _e, _f;
1318
1675
  const { data: session, status } = useSession();
@@ -1344,10 +1701,10 @@ function CommentsSection({ articleSlug, config }) {
1344
1701
  if (!enabled) return null;
1345
1702
  const count = comments.length;
1346
1703
  const label = count === 1 ? "1 comment" : `${count} comments`;
1347
- return /* @__PURE__ */ jsxs18("section", { "aria-label": "Comments", className: "mt-12 pt-8 border-t border-border space-y-6", children: [
1348
- /* @__PURE__ */ jsx20("h2", { className: "text-xl font-semibold text-foreground", children: loading ? "Comments" : label }),
1349
- status === "authenticated" ? /* @__PURE__ */ jsx20(CommentForm, { articleSlug, onSuccess: fetchComments }) : /* @__PURE__ */ jsxs18("p", { className: "text-sm text-muted-foreground", children: [
1350
- /* @__PURE__ */ jsx20(
1704
+ return /* @__PURE__ */ jsxs22("section", { "aria-label": "Comments", className: "mt-12 pt-8 border-t border-border space-y-6", children: [
1705
+ /* @__PURE__ */ jsx24("h2", { className: "text-xl font-semibold text-foreground", children: loading ? "Comments" : label }),
1706
+ status === "authenticated" ? /* @__PURE__ */ jsx24(CommentForm, { articleSlug, onSuccess: fetchComments }) : /* @__PURE__ */ jsxs22("p", { className: "text-sm text-muted-foreground", children: [
1707
+ /* @__PURE__ */ jsx24(
1351
1708
  "button",
1352
1709
  {
1353
1710
  onClick: () => signIn(),
@@ -1358,8 +1715,8 @@ function CommentsSection({ articleSlug, config }) {
1358
1715
  " ",
1359
1716
  "to join the discussion."
1360
1717
  ] }),
1361
- fetchError && /* @__PURE__ */ jsx20("p", { className: "text-sm text-destructive", children: fetchError }),
1362
- loading ? /* @__PURE__ */ jsx20("p", { className: "text-sm text-muted-foreground", children: "Loading comments\u2026" }) : /* @__PURE__ */ jsx20(
1718
+ fetchError && /* @__PURE__ */ jsx24("p", { className: "text-sm text-destructive", children: fetchError }),
1719
+ loading ? /* @__PURE__ */ jsx24("p", { className: "text-sm text-muted-foreground", children: "Loading comments\u2026" }) : /* @__PURE__ */ jsx24(
1363
1720
  CommentThread,
1364
1721
  {
1365
1722
  comments,
@@ -1383,6 +1740,11 @@ export {
1383
1740
  ArticleTOC,
1384
1741
  ArticlesHero,
1385
1742
  ArticlesPage,
1743
+ AuthorArticlesPage,
1744
+ AuthorCard,
1745
+ AuthorDetailHero,
1746
+ AuthorSocialLinks,
1747
+ Breadcrumb,
1386
1748
  BreadcrumbSchema,
1387
1749
  CategoryArticlesPage,
1388
1750
  CollectionPageSchema,
@@ -1398,6 +1760,8 @@ export {
1398
1760
  LatestArticles,
1399
1761
  LatestArticlesSection,
1400
1762
  ScrollToTop,
1763
+ breadcrumbsAreEnabled,
1764
+ getBreadcrumbsConfig,
1401
1765
  useArticles
1402
1766
  };
1403
1767
  //# sourceMappingURL=index.js.map