@fullstackdatasolutions/articles 0.7.1 → 0.8.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.
package/dist/index.js CHANGED
@@ -92,15 +92,19 @@ function ArticleCategoryGrid({ categories, pageSize = 8 }) {
92
92
 
93
93
  // src/ArticleSchemas.tsx
94
94
  import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
95
- function ArticleSchema({ article, articleUrl, siteName }) {
96
- const schema = __spreadProps(__spreadValues({
95
+ function ArticleSchema({
96
+ article,
97
+ articleUrl,
98
+ siteName,
99
+ showAuthor = true
100
+ }) {
101
+ const schema = __spreadProps(__spreadValues(__spreadValues({
97
102
  "@context": "https://schema.org",
98
103
  "@type": "Article",
99
104
  headline: article.title,
100
105
  description: article.excerpt,
101
106
  image: article.featuredImage
102
- }, article.date && { datePublished: new Date(article.date).toISOString() }), {
103
- author: { "@type": "Person", name: article.author },
107
+ }, article.date && { datePublished: new Date(article.date).toISOString() }), showAuthor && { author: { "@type": "Person", name: article.author } }), {
104
108
  publisher: { "@type": "Organization", name: siteName },
105
109
  mainEntityOfPage: { "@type": "WebPage", "@id": articleUrl }
106
110
  });
@@ -131,17 +135,22 @@ function BreadcrumbSchema({ items }) {
131
135
  }
132
136
  );
133
137
  }
134
- function ArticleSEO({ article, articleUrl, siteName, siteLogo }) {
138
+ function ArticleSEO({
139
+ article,
140
+ articleUrl,
141
+ siteName,
142
+ siteLogo,
143
+ showAuthor = true
144
+ }) {
135
145
  const publishedAt = article.date ? new Date(article.date).toISOString() : void 0;
136
146
  const modifiedAt = article.lastmod ? new Date(article.lastmod).toISOString() : publishedAt;
137
- const structuredData = __spreadValues(__spreadProps(__spreadValues(__spreadValues({
147
+ const structuredData = __spreadValues(__spreadProps(__spreadValues(__spreadValues(__spreadValues({
138
148
  "@context": "https://schema.org",
139
149
  "@type": article.articleType || "Article",
140
150
  mainEntityOfPage: { "@type": "WebPage", "@id": articleUrl },
141
151
  headline: article.title,
142
152
  image: article.featuredImage ? { "@type": "ImageObject", url: article.featuredImage } : void 0
143
- }, publishedAt && { datePublished: publishedAt }), modifiedAt && { dateModified: modifiedAt }), {
144
- author: { "@type": "Person", name: article.author },
153
+ }, publishedAt && { datePublished: publishedAt }), modifiedAt && { dateModified: modifiedAt }), showAuthor && { author: { "@type": "Person", name: article.author } }), {
145
154
  publisher: __spreadValues({
146
155
  "@type": "Organization",
147
156
  name: siteName
@@ -310,7 +319,7 @@ import Link3 from "next/link";
310
319
  import Image2 from "next/image";
311
320
  import { ArrowRight, Calendar, Clock, User } from "lucide-react";
312
321
  import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
313
- function FeaturedArticle({ article }) {
322
+ function FeaturedArticle({ article, showAuthor = true }) {
314
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: [
315
324
  /* @__PURE__ */ jsxs5("div", { children: [
316
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" }),
@@ -325,7 +334,7 @@ function FeaturedArticle({ article }) {
325
334
  /* @__PURE__ */ jsx5(Clock, { className: "h-4 w-4" }),
326
335
  /* @__PURE__ */ jsx5("span", { children: article.readTime })
327
336
  ] }),
328
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2", children: [
337
+ showAuthor && /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2", children: [
329
338
  /* @__PURE__ */ jsx5(User, { className: "h-4 w-4" }),
330
339
  /* @__PURE__ */ jsx5("span", { children: article.author })
331
340
  ] })
@@ -615,7 +624,14 @@ function renderSection(section, ctx, config) {
615
624
  "search"
616
625
  );
617
626
  case "featured":
618
- return articles.length > 0 && !searchQuery ? /* @__PURE__ */ jsx9(FeaturedArticle, { article: articles[0] }, "featured") : null;
627
+ return articles.length > 0 && !searchQuery ? /* @__PURE__ */ jsx9(
628
+ FeaturedArticle,
629
+ {
630
+ article: articles[0],
631
+ showAuthor: config.showAuthor !== false
632
+ },
633
+ "featured"
634
+ ) : null;
619
635
  case "latest":
620
636
  if (loading && articles.length === 0) {
621
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: [
@@ -698,7 +714,8 @@ function toSlug(cat) {
698
714
  function ArticleDetailHero({
699
715
  article,
700
716
  categoryBasePath = "/articles/category",
701
- showDate = false
717
+ showDate = false,
718
+ showAuthor = true
702
719
  }) {
703
720
  return /* @__PURE__ */ jsxs10(
704
721
  "section",
@@ -799,7 +816,7 @@ function ArticleDetailHero({
799
816
  /* @__PURE__ */ jsx10(Clock3, { className: "h-4 w-4" }),
800
817
  /* @__PURE__ */ jsx10("span", { children: article.readTime })
801
818
  ] }),
802
- /* @__PURE__ */ jsxs10("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
819
+ showAuthor && /* @__PURE__ */ jsxs10("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
803
820
  /* @__PURE__ */ jsx10(User2, { className: "h-4 w-4" }),
804
821
  /* @__PURE__ */ jsxs10("span", { children: [
805
822
  "By ",
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ArticleCategoryGrid.tsx","../src/ArticleSchemas.tsx","../src/ArticleSearchBar.tsx","../src/ArticlesHero.tsx","../src/FeaturedArticle.tsx","../src/LatestArticlesSection.tsx","../src/LatestArticles.tsx","../src/ArticleCard.tsx","../src/articlesConfig.ts","../src/useArticles.ts","../src/ArticlesPage.tsx","../src/ArticleDetailHero.tsx","../src/CategoryArticlesPage.tsx","../src/ArticleSocialShare.tsx","../src/ArticleNavigation.tsx","../src/ArticleBackLink.tsx","../src/ArticleTOC.tsx","../src/ScrollToTop.tsx","../src/CommentsSection.tsx","../src/CommentForm.tsx","../src/CommentItem.tsx","../src/CommentThread.tsx"],"sourcesContent":["'use client'\n\nimport Image from 'next/image'\nimport Link from 'next/link'\nimport { useState, useEffect } from 'react'\nimport type { CategoryInfo } from './articleTypes'\n\ntype ArticleCategoryGridProps = Readonly<{\n categories: CategoryInfo[]\n pageSize?: number\n}>\n\nexport function ArticleCategoryGrid({ categories, pageSize = 8 }: ArticleCategoryGridProps) {\n const [visibleCount, setVisibleCount] = useState(pageSize)\n\n useEffect(() => {\n setVisibleCount(pageSize)\n }, [categories, pageSize])\n\n if (categories.length === 0) return null\n\n const visible = categories.slice(0, visibleCount)\n const hasMore = visibleCount < categories.length\n\n return (\n <section className=\"py-16 bg-background\">\n <div className=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8\">\n <div className=\"text-center mb-12\">\n <h2 className=\"text-3xl font-bold text-foreground mb-4\">Browse by Category</h2>\n <p className=\"text-lg text-muted-foreground\">\n Explore our articles by topic to find the insights most relevant to your interests.\n </p>\n </div>\n\n <div className=\"grid md:grid-cols-2 lg:grid-cols-3 gap-6\">\n {visible.map((cat) => (\n <Link key={cat.slug} href={`/articles/category/${cat.slug}`}>\n <div className=\"group overflow-hidden rounded-xl border border-border shadow-sm hover:shadow-lg transition-all duration-300 cursor-pointer bg-card\">\n <div className=\"overflow-hidden\" style={{ position: 'relative', height: '13rem' }}>\n <Image\n src={cat.featuredImage}\n alt={cat.name}\n fill\n sizes=\"(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw\"\n className=\"object-cover group-hover:scale-105 transition-transform duration-300\"\n />\n </div>\n <div className=\"p-4 text-center\">\n <h3 className=\"font-semibold text-foreground text-base\">{cat.name}</h3>\n <p className=\"text-sm text-muted-foreground mt-1\">\n {cat.count} {cat.count === 1 ? 'article' : 'articles'}\n </p>\n </div>\n </div>\n </Link>\n ))}\n </div>\n\n {hasMore && (\n <div className=\"mt-10 text-center\">\n <button\n type=\"button\"\n onClick={() => setVisibleCount((c) => c + pageSize)}\n className=\"inline-flex items-center justify-center px-4 py-2 border border-input bg-background hover:bg-accent rounded-md font-medium text-sm transition-colors\"\n >\n Load more categories\n </button>\n </div>\n )}\n </div>\n </section>\n )\n}\n","import { Article, FaqItem, HowToStep } from './articleTypes'\n\ntype ArticleSchemaProps = Readonly<{\n article: Article\n articleUrl: string\n siteName: string\n}>\n\nexport function ArticleSchema({ article, articleUrl, siteName }: ArticleSchemaProps) {\n const schema = {\n '@context': 'https://schema.org',\n '@type': 'Article',\n headline: article.title,\n description: article.excerpt,\n image: article.featuredImage,\n ...(article.date && { datePublished: new Date(article.date).toISOString() }),\n author: { '@type': 'Person', name: article.author },\n publisher: { '@type': 'Organization', name: siteName },\n mainEntityOfPage: { '@type': 'WebPage', '@id': articleUrl },\n }\n\n return (\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}\n />\n )\n}\n\ntype BreadcrumbSchemaProps = Readonly<{\n items: ReadonlyArray<{ name: string; url: string }>\n}>\n\nexport function BreadcrumbSchema({ items }: BreadcrumbSchemaProps) {\n const schema = {\n '@context': 'https://schema.org',\n '@type': 'BreadcrumbList',\n itemListElement: items.map((item, index) => ({\n '@type': 'ListItem',\n position: index + 1,\n name: item.name,\n item: item.url,\n })),\n }\n\n return (\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}\n />\n )\n}\n\ntype ArticleSEOProps = Readonly<{\n article: Article\n articleUrl: string\n siteName: string\n siteLogo?: string\n}>\n\nexport function ArticleSEO({ article, articleUrl, siteName, siteLogo }: ArticleSEOProps) {\n const publishedAt = article.date ? new Date(article.date).toISOString() : undefined\n const modifiedAt = article.lastmod ? new Date(article.lastmod).toISOString() : publishedAt\n\n const structuredData = {\n '@context': 'https://schema.org',\n '@type': article.articleType || 'Article',\n mainEntityOfPage: { '@type': 'WebPage', '@id': articleUrl },\n headline: article.title,\n image: article.featuredImage\n ? { '@type': 'ImageObject', url: article.featuredImage }\n : undefined,\n ...(publishedAt && { datePublished: publishedAt }),\n ...(modifiedAt && { dateModified: modifiedAt }),\n author: { '@type': 'Person', name: article.author },\n publisher: {\n '@type': 'Organization',\n name: siteName,\n ...(siteLogo && { logo: { '@type': 'ImageObject', url: siteLogo } }),\n },\n description: article.excerpt,\n ...(article.series && { isPartOf: { '@type': 'Blog', name: article.series } }),\n }\n\n return (\n <>\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{ __html: JSON.stringify(structuredData) }}\n />\n {article.faq && article.faq.length > 0 && (\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{\n __html: JSON.stringify({\n '@context': 'https://schema.org',\n '@type': 'FAQPage',\n mainEntity: article.faq.map(({ question, answer }: FaqItem) => ({\n '@type': 'Question',\n name: question,\n acceptedAnswer: { '@type': 'Answer', text: answer },\n })),\n }),\n }}\n />\n )}\n {article.howTo && article.howTo.length > 0 && (\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{\n __html: JSON.stringify({\n '@context': 'https://schema.org',\n '@type': 'HowTo',\n name: article.title,\n step: article.howTo.map(({ name, text }: HowToStep) => ({\n '@type': 'HowToStep',\n name,\n text,\n })),\n }),\n }}\n />\n )}\n </>\n )\n}\n\ntype FAQPageSchemaProps = Readonly<{\n items: ReadonlyArray<{ question: string; answer: string }>\n}>\n\nexport function FAQPageSchema({ items }: FAQPageSchemaProps) {\n const schema = {\n '@context': 'https://schema.org',\n '@type': 'FAQPage',\n mainEntity: items.map(({ question, answer }) => ({\n '@type': 'Question',\n name: question,\n acceptedAnswer: { '@type': 'Answer', text: answer },\n })),\n }\n return (\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}\n />\n )\n}\n\ntype CollectionPageSchemaProps = Readonly<{\n title: string\n description: string\n url: string\n articleCount: number\n}>\n\nexport function CollectionPageSchema({\n title,\n description,\n url,\n articleCount,\n}: CollectionPageSchemaProps) {\n const schema = {\n '@context': 'https://schema.org',\n '@type': 'CollectionPage',\n name: title,\n description,\n url,\n numberOfItems: articleCount,\n }\n\n return (\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}\n />\n )\n}\n","import { Search, X } from 'lucide-react'\n\ntype ArticleSearchBarProps = Readonly<{\n value: string\n onChange: (query: string) => void\n disabled?: boolean\n resultCount?: number\n}>\n\nexport function ArticleSearchBar({\n value,\n onChange,\n disabled,\n resultCount,\n}: ArticleSearchBarProps) {\n return (\n <section className=\"py-8 bg-background border-b border-border\">\n <div className=\"max-w-4xl mx-auto px-4 sm:px-6 lg:px-8\">\n <div className=\"relative\">\n <Search className=\"absolute left-3 top-1/2 transform -translate-y-1/2 text-muted-foreground h-5 w-5\" />\n <input\n type=\"text\"\n placeholder=\"Search articles (3+ characters required)...\"\n value={value}\n onChange={(e) => onChange(e.target.value)}\n disabled={disabled}\n 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\"\n />\n {value && (\n <button\n type=\"button\"\n onClick={() => onChange('')}\n aria-label=\"Clear search\"\n className=\"absolute right-3 top-1/2 transform -translate-y-1/2 text-muted-foreground hover:text-foreground\"\n >\n <X className=\"h-5 w-5\" />\n </button>\n )}\n </div>\n {value && (\n <div className=\"mt-2 text-sm text-muted-foreground\">\n {resultCount === 0\n ? 'No articles found matching your search.'\n : `Found ${resultCount} article${resultCount === 1 ? '' : 's'} matching \"${value}\"`}\n </div>\n )}\n </div>\n </section>\n )\n}\n","import Link from 'next/link'\n\nconst DEFAULT_TITLE = 'Vox Populus Insights'\nconst DEFAULT_DESCRIPTION =\n 'Expert analysis, campaign strategies, and voter engagement insights from the frontlines of democracy.'\n\ntype ArticlesHeroProps = Readonly<{\n title?: string\n description?: string\n}>\n\nexport function ArticlesHero({\n title = DEFAULT_TITLE,\n description = DEFAULT_DESCRIPTION,\n}: ArticlesHeroProps) {\n return (\n <section className=\"bg-linear-to-r from-gray-50 to-gray-100 py-16 md:py-24\">\n <div className=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8\">\n <div className=\"max-w-3xl mx-auto text-center\">\n <h1 className=\"text-4xl md:text-5xl font-bold text-foreground mb-6\">{title}</h1>\n <p className=\"text-xl text-muted-foreground mb-8\">{description}</p>\n <div className=\"flex flex-col sm:flex-row gap-4 justify-center\">\n <Link\n href=\"#latest\"\n 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\"\n >\n Browse Latest Articles\n </Link>\n <Link\n href=\"/contact\"\n 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\"\n >\n Contact Our Team\n </Link>\n </div>\n </div>\n </div>\n </section>\n )\n}\n","import Link from 'next/link'\nimport Image from 'next/image'\nimport { ArrowRight, Calendar, Clock, User } from 'lucide-react'\nimport type { Article } from './articleTypes'\n\ntype FeaturedArticleProps = Readonly<{\n article: Article\n}>\n\nexport function FeaturedArticle({ article }: FeaturedArticleProps) {\n return (\n <section className=\"py-16 bg-background\">\n <div className=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8\">\n <div className=\"grid lg:grid-cols-2 gap-12 items-center\">\n <div>\n <span className=\"inline-block bg-primary/10 text-primary text-sm font-medium px-3 py-1 rounded-full mb-4\">\n FEATURED ARTICLE\n </span>\n <h2 className=\"text-3xl font-bold text-foreground mb-4\">{article.title}</h2>\n <p className=\"text-lg text-muted-foreground mb-6\">{article.excerpt}</p>\n <div className=\"flex items-center gap-6 text-sm text-muted-foreground mb-6\">\n {article.date && (\n <div className=\"flex items-center gap-2\">\n <Calendar className=\"h-4 w-4\" />\n <span>{article.date}</span>\n </div>\n )}\n <div className=\"flex items-center gap-2\">\n <Clock className=\"h-4 w-4\" />\n <span>{article.readTime}</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <User className=\"h-4 w-4\" />\n <span>{article.author}</span>\n </div>\n </div>\n <Link\n href={`/articles/${article.slug}`}\n 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\"\n >\n Read Full Article\n <ArrowRight className=\"ml-2 h-4 w-4\" />\n </Link>\n </div>\n <div className=\"bg-card rounded-lg p-8\">\n <Image\n src={article.featuredImage}\n alt={article.title}\n width={800}\n height={450}\n className=\"w-full h-64 object-cover rounded-lg mb-4\"\n />\n <div className=\"flex gap-2\">\n <span className=\"bg-primary/10 text-primary text-xs font-medium px-2 py-1 rounded\">\n {article.category}\n </span>\n </div>\n </div>\n </div>\n </div>\n </section>\n )\n}\n","'use client'\n\nimport { Search } from 'lucide-react'\nimport type { Article } from './articleTypes'\nimport { LatestArticles } from './LatestArticles'\n\ninterface LatestArticlesSectionProps {\n readonly articles: Article[]\n readonly searchQuery: string\n readonly onClearSearch: () => void\n readonly pageSize?: number\n}\n\nfunction DescriptionText({\n searchQuery,\n count,\n}: {\n readonly searchQuery: string\n readonly count: number\n}) {\n const pluralSuffix = count === 1 ? '' : 's'\n const text = searchQuery\n ? `Found ${count} article${pluralSuffix} matching your search.`\n : 'Stay informed with our latest insights on voter engagement, campaign strategies, and civic technology.'\n return <p className=\"text-lg text-muted-foreground\">{text}</p>\n}\n\nexport function LatestArticlesSection({\n articles,\n searchQuery,\n onClearSearch,\n pageSize = 6,\n}: Readonly<LatestArticlesSectionProps>) {\n return (\n <section id=\"latest\" className=\"py-16 bg-muted/50\">\n <div className=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8\">\n <div className=\"text-center mb-12\">\n <h2 className=\"text-3xl font-bold text-foreground mb-4\">\n {searchQuery ? 'Search Results' : 'Latest Articles'}\n </h2>\n <DescriptionText searchQuery={searchQuery} count={articles.length} />\n </div>\n\n {articles.length === 0 && searchQuery ? (\n <div className=\"text-center py-12\">\n <div className=\"max-w-md mx-auto\">\n <Search className=\"h-12 w-12 text-muted-foreground mx-auto mb-4\" />\n <h3 className=\"text-lg font-semibold text-foreground mb-2\">No articles found</h3>\n <p className=\"text-muted-foreground mb-4\">\n We couldn&apos;t find any articles matching &quot;{searchQuery}&quot;. Try adjusting\n your search terms.\n </p>\n <button\n type=\"button\"\n onClick={onClearSearch}\n className=\"inline-flex items-center justify-center px-4 py-2 border border-input bg-background hover:bg-accent rounded-md font-medium text-sm transition-colors\"\n >\n Clear search\n </button>\n </div>\n </div>\n ) : (\n <LatestArticles articles={articles} pageSize={pageSize} key={searchQuery} />\n )}\n </div>\n </section>\n )\n}\n","'use client'\n\nimport { useState, useEffect } from 'react'\nimport type { Article } from './articleTypes'\nimport { ArticleCard } from './ArticleCard'\n\ninterface LatestArticlesProps {\n readonly articles: Article[]\n readonly pageSize: number\n}\n\nexport function LatestArticles({ articles, pageSize }: Readonly<LatestArticlesProps>) {\n const [visibleCount, setVisibleCount] = useState(pageSize)\n\n useEffect(() => {\n setVisibleCount(pageSize)\n }, [articles, pageSize])\n\n const visible = articles.slice(0, visibleCount)\n const hasMore = visibleCount < articles.length\n\n return (\n <div>\n <div className=\"grid md:grid-cols-2 lg:grid-cols-3 gap-8\">\n {visible.map((article) => (\n <ArticleCard key={article.slug} article={article} />\n ))}\n </div>\n {hasMore && (\n <div className=\"mt-10 text-center\">\n <button\n type=\"button\"\n onClick={() => setVisibleCount((c) => c + pageSize)}\n className=\"inline-flex items-center justify-center px-4 py-2 border border-input bg-background hover:bg-accent rounded-md font-medium text-sm transition-colors\"\n >\n Load more articles\n </button>\n </div>\n )}\n </div>\n )\n}\n","'use client'\n\nimport Image from 'next/image'\nimport Link from 'next/link'\nimport { ArrowRight, Calendar, Clock } from 'lucide-react'\nimport type { Article } from './articleTypes'\n\ntype ArticleCardProps = Readonly<{\n article: Article\n}>\n\nexport function ArticleCard({ article }: ArticleCardProps) {\n return (\n <div className=\"rounded-lg border border-border bg-card text-card-foreground shadow-sm hover:shadow-lg transition-shadow duration-300\">\n <div className=\"p-0\">\n <Image\n src={article.featuredImage}\n alt={article.title}\n className=\"w-full h-48 object-cover rounded-t-lg\"\n width={400}\n height={200}\n />\n </div>\n <div className=\"p-6\">\n <div className=\"flex gap-2 mb-3\">\n <span className=\"bg-primary/10 text-primary text-xs font-medium px-2 py-1 rounded\">\n {article.category}\n </span>\n </div>\n <h3 className=\"text-lg font-semibold leading-none tracking-tight mb-2\">\n <Link\n href={`/articles/${article.slug}`}\n className=\"hover:text-indigo-600 transition-colors\"\n >\n {article.title}\n </Link>\n </h3>\n <p className=\"text-muted-foreground mb-4 line-clamp-3\">{article.excerpt}</p>\n <div className=\"flex items-center justify-between text-sm text-muted-foreground border-t pt-4\">\n <div className=\"flex items-center gap-3\">\n {article.date && (\n <div className=\"flex items-center gap-2\">\n <Calendar className=\"h-3 w-3\" />\n <span>{article.date}</span>\n </div>\n )}\n <div className=\"flex items-center gap-2\">\n <Clock className=\"h-3 w-3\" />\n <span>{article.readTime}</span>\n </div>\n </div>\n <Link\n href={`/articles/${article.slug}`}\n className=\"inline-flex items-center justify-center h-8 w-8 p-0 rounded-md hover:bg-accent transition-colors\"\n aria-label={`Read ${article.title}`}\n >\n <ArrowRight className=\"h-4 w-4\" />\n </Link>\n </div>\n </div>\n </div>\n )\n}\n","/** Keys for each renderable section of the articles listing page. */\nexport type ArticlesSection =\n | 'hero'\n | 'search'\n | 'featured'\n | 'latest'\n | 'categories'\n | 'newsletter'\n\n/**\n * CSS custom-property overrides applied to the library's wrapper div.\n * All fields are optional; omitted fields fall back to the consuming app's Tailwind theme.\n */\nexport interface ArticlesTheme {\n /** Font family for the articles section. Example: `\"'Inter', sans-serif\"` */\n fontFamily?: string\n /** Color for article card titles and section headings. Example: `'#111827'` */\n headerColor?: string\n /** Color for body and excerpt text. Example: `'#6b7280'` */\n textColor?: string\n /** Background color for sections and cards. Example: `'#ffffff'` */\n backgroundColor?: string\n /** Color for \"Read More\" links and inline links. Example: `'#4f46e5'` */\n linkColor?: string\n /** Hover color for links. Example: `'#4338ca'` */\n linkHoverColor?: string\n /** Text decoration for links. Values: `'underline'` | `'none'` */\n linkTextDecoration?: string\n /** Font weight for headings. Example: `700` */\n headerFontWeight?: string | number\n /** Font size for article card titles. Example: `'1.25rem'` */\n headerFontSize?: string\n /** Font size for body text. Example: `'1rem'` */\n bodyFontSize?: string\n /** Line height for body text. Example: `'1.75'` */\n lineHeight?: string\n /** Border radius for cards. Example: `'0.5rem'` */\n borderRadius?: string\n}\n\n/** Per-category text used in meta descriptions and on the category hero page. */\nexport interface CategoryDescription {\n /** Short description — used in meta description and category grid card. */\n short: string\n /** Long description — rendered as a hero paragraph on the category page. */\n long?: string\n}\n\n/** Controls the comments feature. Attach to `ArticlesConfig.comments`. */\nexport interface CommentsConfig {\n /** Set to `true` to enable comments globally across all articles. */\n enabled: boolean\n /** Maximum reply nesting depth. Default: `1` (replies to top-level only). */\n maxDepth?: number\n /**\n * Per-article overrides keyed by slug.\n * Example: `{ 'sensitive-article': false }` disables comments on that article only.\n */\n perArticleOverride?: Record<string, boolean>\n}\n\n/** Text content for the hero section at the top of the articles listing page. */\nexport interface HeroConfig {\n /** Main heading displayed in the hero. Default: `'Vox Populus Insights'` */\n title?: string\n /** Subheading paragraph displayed beneath the title. Default: the built-in description. */\n description?: string\n}\n\n/** Top-level configuration object. Pass one instance to every library component. */\nexport interface ArticlesConfig {\n /** Canonical base URL of the site, used in metadata and JSON-LD. Example: `'https://yoursite.com'` */\n siteUrl: string\n /** Site name shown in metadata titles and JSON-LD publisher fields. Example: `'Vox Populus'` */\n siteName: string\n /** Number of articles shown per page in the grid and loaded on each \"Load more\" click. Default: `6` */\n pageSize?: number\n /** Number of category cards shown before a \"Load more categories\" button appears. Default: `8` */\n categoriesPageSize?: number\n /**\n * Ordered list of sections to render on the articles listing page.\n * Omit a key to hide that section entirely. Default: `['hero','search','featured','latest','categories']`\n */\n layout?: ArticlesSection[]\n /** CSS custom-property overrides for colors, fonts, and spacing. All fields optional. */\n theme?: ArticlesTheme\n /**\n * Descriptive text for each category, keyed by category slug.\n * A plain string is treated as the short description only.\n * Example: `{ 'campaigns': { short: 'Campaign tips', long: 'Full paragraph...' } }`\n */\n categoryDescriptions?: Record<string, string | CategoryDescription>\n /** Comments configuration. Omit or set `enabled: false` to hide comments entirely. */\n comments?: CommentsConfig\n /** Hero section title and description. Omit to use the built-in defaults. */\n hero?: HeroConfig\n /** Short description used in the RSS feed channel. Falls back to siteName if omitted. */\n description?: string\n /** Set to false to hide the table of contents on article detail pages. Default: true. */\n showToc?: boolean\n /** Set to false to hide the \"Back to Articles\" navigation link on article detail pages. Default: true. */\n showBackToArticles?: boolean\n}\n\nexport const DEFAULT_PAGE_SIZE = 6\nexport const DEFAULT_CATEGORIES_PAGE_SIZE = 8\n\nexport const DEFAULT_LAYOUT: ArticlesSection[] = [\n 'hero',\n 'search',\n 'featured',\n 'latest',\n 'categories',\n]\n","'use client'\n\nimport { useState, useCallback, useEffect, useRef } from 'react'\nimport { Article, CategoryInfo } from './articleTypes'\n\nexport interface UseArticlesReturn {\n articles: Article[]\n categories: CategoryInfo[]\n searchQuery: string\n loading: boolean\n error: string | null\n handleSearch: (query: string) => void\n}\n\nexport function useArticles(): UseArticlesReturn {\n const [searchQuery, setSearchQuery] = useState('')\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n const [articles, setArticles] = useState<Article[]>([])\n const [categories, setCategories] = useState<CategoryInfo[]>([])\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState<string | null>(null)\n\n const fetchArticles = useCallback(async (query: string) => {\n try {\n setLoading(true)\n const url = query ? `/api/articles?q=${encodeURIComponent(query)}` : '/api/articles'\n const response = await fetch(url)\n\n if (!response.ok) throw new Error('Failed to fetch articles')\n\n const data = await response.json()\n setArticles(data.articles)\n\n if (!query?.trim()) {\n const catMap = new Map<string, { count: number; featuredImage: string }>()\n for (const article of data.articles as Article[]) {\n for (const cat of article.categories) {\n if (!catMap.has(cat)) {\n catMap.set(cat, { count: 0, featuredImage: article.featuredImage })\n }\n catMap.get(cat)!.count++\n }\n }\n setCategories(\n Array.from(catMap.entries())\n .map(([name, { count, featuredImage }]) => ({\n name,\n slug: name\n .toLowerCase()\n .replaceAll(/\\s+/g, '-')\n .replaceAll(/[^a-z0-9-]/g, ''),\n count,\n featuredImage,\n }))\n .sort((a, b) => b.count - a.count)\n )\n }\n\n setError(null)\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to load articles')\n setArticles([])\n } finally {\n setLoading(false)\n }\n }, [])\n\n useEffect(() => {\n fetchArticles('')\n }, [fetchArticles])\n\n const handleSearch = useCallback(\n (query: string) => {\n setSearchQuery(query)\n if (debounceRef.current) clearTimeout(debounceRef.current)\n if (query === '') {\n fetchArticles('')\n } else if (query.length >= 3) {\n debounceRef.current = setTimeout(() => fetchArticles(query), 1000)\n }\n },\n [fetchArticles]\n )\n\n useEffect(\n () => () => {\n if (debounceRef.current) clearTimeout(debounceRef.current)\n },\n []\n )\n\n return { articles, categories, searchQuery, loading, error, handleSearch }\n}\n","'use client'\n\nimport React from 'react'\nimport type { Article, CategoryInfo } from './articleTypes'\nimport { ArticleCategoryGrid } from './ArticleCategoryGrid'\nimport { CollectionPageSchema } from './ArticleSchemas'\nimport { ArticleSearchBar } from './ArticleSearchBar'\nimport { ArticlesHero } from './ArticlesHero'\nimport { FeaturedArticle } from './FeaturedArticle'\nimport { LatestArticlesSection } from './LatestArticlesSection'\nimport {\n ArticlesConfig,\n ArticlesSection,\n ArticlesTheme,\n DEFAULT_CATEGORIES_PAGE_SIZE,\n DEFAULT_LAYOUT,\n DEFAULT_PAGE_SIZE,\n} from './articlesConfig'\nimport { useArticles } from './useArticles'\n\ninterface SectionContext {\n articles: Article[]\n displayedArticles: Article[]\n categories: CategoryInfo[]\n searchQuery: string\n loading: boolean\n error: string | null\n handleSearch: (query: string) => void\n pageSize: number\n categoriesPageSize: number\n}\n\nfunction buildThemeVars(theme?: ArticlesTheme): React.CSSProperties {\n if (!theme) return {}\n const vars: Record<string, string> = {}\n if (theme.fontFamily) vars['--articles-font-family'] = theme.fontFamily\n if (theme.headerColor) vars['--articles-header-color'] = theme.headerColor\n if (theme.textColor) vars['--articles-text-color'] = theme.textColor\n if (theme.backgroundColor) vars['--articles-bg-color'] = theme.backgroundColor\n if (theme.linkColor) vars['--articles-link-color'] = theme.linkColor\n if (theme.linkHoverColor) vars['--articles-link-hover-color'] = theme.linkHoverColor\n if (theme.linkTextDecoration) vars['--articles-link-decoration'] = theme.linkTextDecoration\n if (theme.headerFontWeight) vars['--articles-header-font-weight'] = String(theme.headerFontWeight)\n if (theme.headerFontSize) vars['--articles-header-font-size'] = theme.headerFontSize\n if (theme.bodyFontSize) vars['--articles-body-font-size'] = theme.bodyFontSize\n if (theme.lineHeight) vars['--articles-line-height'] = theme.lineHeight\n if (theme.borderRadius) vars['--articles-border-radius'] = theme.borderRadius\n return vars as React.CSSProperties\n}\n\nfunction renderSection(\n section: ArticlesSection,\n ctx: SectionContext,\n config: ArticlesConfig\n): React.ReactNode {\n const {\n articles,\n displayedArticles,\n categories,\n searchQuery,\n loading,\n error,\n handleSearch,\n pageSize,\n categoriesPageSize,\n } = ctx\n\n switch (section) {\n case 'hero':\n return (\n <ArticlesHero\n key=\"hero\"\n title={config.hero?.title}\n description={config.hero?.description}\n />\n )\n\n case 'search':\n return (\n <ArticleSearchBar\n key=\"search\"\n value={searchQuery}\n onChange={handleSearch}\n disabled={loading}\n resultCount={articles.length}\n />\n )\n\n case 'featured':\n return articles.length > 0 && !searchQuery ? (\n <FeaturedArticle key=\"featured\" article={articles[0]} />\n ) : null\n\n case 'latest':\n if (loading && articles.length === 0) {\n return (\n <section key=\"latest\" id=\"latest\" className=\"py-16 bg-muted/50 flex-1\">\n <div className=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex items-center justify-center py-24\">\n <div className=\"text-center\">\n <div className=\"animate-spin rounded-full h-12 w-12 border-b-2 border-primary mx-auto mb-4\" />\n <p className=\"text-muted-foreground\">Loading articles...</p>\n </div>\n </div>\n </section>\n )\n }\n if (error) {\n return (\n <section key=\"latest\" id=\"latest\" className=\"py-16 bg-muted/50 flex-1\">\n <div className=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex items-center justify-center\">\n <div className=\"bg-red-50 border border-red-200 rounded-lg p-6 max-w-md text-center\">\n <h3 className=\"text-lg font-semibold text-red-800 mb-2\">Error Loading Articles</h3>\n <p className=\"text-red-600 mb-4\">{error}</p>\n <button\n type=\"button\"\n onClick={() => handleSearch('')}\n className=\"inline-flex items-center justify-center px-4 py-2 border border-input bg-background hover:bg-accent rounded-md font-medium text-sm transition-colors\"\n >\n Try again\n </button>\n </div>\n </div>\n </section>\n )\n }\n return (\n <LatestArticlesSection\n key=\"latest\"\n articles={displayedArticles}\n searchQuery={searchQuery}\n onClearSearch={() => handleSearch('')}\n pageSize={pageSize}\n />\n )\n\n case 'categories':\n return searchQuery ? null : (\n <ArticleCategoryGrid\n key=\"categories\"\n categories={categories}\n pageSize={categoriesPageSize}\n />\n )\n\n // 'newsletter' is intentionally omitted — inject it via the layout prop in the consuming app\n default:\n return null\n }\n}\n\nexport function ArticlesPage({ config }: Readonly<{ config: ArticlesConfig }>) {\n const state = useArticles()\n const layout = config.layout ?? DEFAULT_LAYOUT\n const pageSize = config.pageSize ?? DEFAULT_PAGE_SIZE\n const categoriesPageSize = config.categoriesPageSize ?? DEFAULT_CATEGORIES_PAGE_SIZE\n const themeVars = buildThemeVars(config.theme)\n\n const hasFeatured = layout.includes('featured')\n const articlesWithoutFeatured = hasFeatured ? state.articles.slice(1) : state.articles\n const displayedArticles = state.searchQuery ? state.articles : articlesWithoutFeatured\n\n const ctx: SectionContext = { ...state, displayedArticles, pageSize, categoriesPageSize }\n\n return (\n <div style={themeVars}>\n {layout.map((section) => renderSection(section, ctx, config))}\n {state.articles.length > 0 && (\n <CollectionPageSchema\n title={`Articles | ${config.siteName}`}\n description={`Browse all ${state.articles.length} articles on ${config.siteName}.`}\n url={`${config.siteUrl}/articles`}\n articleCount={state.articles.length}\n />\n )}\n </div>\n )\n}\n","import Image from 'next/image'\nimport Link from 'next/link'\nimport { Calendar, Clock, User } from 'lucide-react'\nimport type { Article } from './articleTypes'\n\ntype ArticleDetailHeroProps = Readonly<{\n article: Article\n categoryBasePath?: string\n showDate?: boolean\n}>\n\nfunction toSlug(cat: string): string {\n return cat\n .toLowerCase()\n .replaceAll(/\\s+/g, '-')\n .replaceAll(/[^a-z0-9-]/g, '')\n}\n\nexport function ArticleDetailHero({\n article,\n categoryBasePath = '/articles/category',\n showDate = false,\n}: ArticleDetailHeroProps) {\n return (\n <section\n style={{\n position: 'relative',\n height: '18rem',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n overflow: 'hidden',\n }}\n >\n <Image\n src={article.featuredImage}\n alt={article.title}\n fill\n sizes=\"100vw\"\n className=\"object-cover\"\n style={{ objectFit: 'cover' }}\n priority\n />\n <div\n style={{\n position: 'absolute',\n inset: 0,\n backgroundColor: 'rgba(0,0,0,0.6)',\n }}\n />\n <div\n style={{\n position: 'relative',\n zIndex: 10,\n textAlign: 'center',\n color: 'white',\n padding: '0 1rem',\n maxWidth: '56rem',\n margin: '0 auto',\n width: '100%',\n }}\n >\n {article.categories && article.categories.length > 0 && (\n <div\n style={{\n display: 'flex',\n flexWrap: 'wrap',\n justifyContent: 'center',\n gap: '0.5rem',\n marginBottom: '1rem',\n }}\n >\n {article.categories.slice(0, 4).map((cat) =>\n categoryBasePath ? (\n <Link\n key={cat}\n href={`${categoryBasePath}/${toSlug(cat)}`}\n className=\"inline-block bg-white/20 text-white text-sm font-medium px-3 py-1 rounded-full hover:bg-white/30 transition-colors\"\n >\n {cat}\n </Link>\n ) : (\n <span\n key={cat}\n className=\"inline-block bg-white/20 text-white text-sm font-medium px-3 py-1 rounded-full\"\n >\n {cat}\n </span>\n )\n )}\n </div>\n )}\n <h1 className=\"text-4xl md:text-5xl font-bold mb-4\">{article.title}</h1>\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '1.5rem',\n fontSize: '0.875rem',\n color: 'rgba(255,255,255,0.8)',\n }}\n >\n {showDate && article.date && (\n <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>\n <Calendar className=\"h-4 w-4\" />\n <span>{article.date}</span>\n </div>\n )}\n <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>\n <Clock className=\"h-4 w-4\" />\n <span>{article.readTime}</span>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>\n <User className=\"h-4 w-4\" />\n <span>By {article.author}</span>\n </div>\n </div>\n </div>\n </section>\n )\n}\n","'use client'\n\nimport Image from 'next/image'\nimport Link from 'next/link'\nimport { BreadcrumbSchema } from './ArticleSchemas'\nimport { LatestArticles } from './LatestArticles'\nimport { ArticlesConfig, DEFAULT_PAGE_SIZE } from './articlesConfig'\nimport type { Article } from './articleTypes'\n\nfunction getCategoryDescription(\n config: ArticlesConfig,\n slug: string,\n categoryName: string\n): { short: string; long?: string } {\n const raw = config.categoryDescriptions?.[slug]\n if (!raw) return { short: `Browse all articles in ${categoryName}.` }\n if (typeof raw === 'string') return { short: raw }\n return raw\n}\n\ntype CategoryArticlesPageProps = Readonly<{\n category: string\n articles: Article[]\n config: ArticlesConfig\n}>\n\nexport function CategoryArticlesPage({ category, articles, config }: CategoryArticlesPageProps) {\n if (articles.length === 0) return null\n\n const categoryName = articles[0].category\n const heroImage = articles[0].featuredImage\n const description = getCategoryDescription(config, category, categoryName)\n const pageSize = config.pageSize ?? DEFAULT_PAGE_SIZE\n const siteUrl = config.siteUrl.replace(/\\/$/, '')\n\n return (\n <div>\n <BreadcrumbSchema\n items={[\n { name: 'Home', url: siteUrl },\n { name: 'Articles', url: `${siteUrl}/articles` },\n { name: categoryName, url: `${siteUrl}/articles/category/${category}` },\n ]}\n />\n {/* Hero */}\n <section\n style={{\n position: 'relative',\n height: '20rem',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n overflow: 'hidden',\n }}\n >\n <Image\n src={heroImage}\n alt={categoryName}\n fill\n sizes=\"100vw\"\n style={{ objectFit: 'cover' }}\n priority\n />\n <div style={{ position: 'absolute', inset: 0, backgroundColor: 'rgba(0,0,0,0.6)' }} />\n <div\n style={{\n position: 'relative',\n zIndex: 10,\n textAlign: 'center',\n color: 'white',\n padding: '0 1rem',\n }}\n >\n <p className=\"text-sm font-semibold uppercase tracking-widest mb-3 opacity-80\">\n Category\n </p>\n <h1 className=\"text-4xl md:text-5xl font-bold mb-3\">{categoryName}</h1>\n {description.long && (\n <p className=\"text-lg opacity-90 max-w-2xl mx-auto mt-2\">{description.long}</p>\n )}\n <p className=\"text-lg opacity-70 mt-2\">\n {articles.length} article{articles.length === 1 ? '' : 's'}\n </p>\n </div>\n </section>\n\n {/* Articles */}\n <section className=\"py-16 bg-muted/50 flex-1\">\n <div className=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8\">\n <div className=\"mb-8 flex items-center justify-between\">\n <Link href=\"/articles\" className=\"text-sm text-primary hover:underline\">\n ← All Articles\n </Link>\n <p className=\"text-sm text-muted-foreground\">{description.short}</p>\n </div>\n <LatestArticles articles={articles} pageSize={pageSize} />\n </div>\n </section>\n </div>\n )\n}\n","'use client'\n\nimport { useState } from 'react'\nimport { Share2, Copy, Check, Mail, MessageCircle, Users, FileText } from 'lucide-react'\n\ninterface ArticleSocialShareProps {\n readonly title: string\n readonly url: string\n readonly excerpt?: string\n readonly shareMessage?: string\n}\n\nexport function ArticleSocialShare({ title, url, excerpt, shareMessage }: ArticleSocialShareProps) {\n const [copied, setCopied] = useState(false)\n\n const encodedTitle = encodeURIComponent(title)\n const encodedUrl = encodeURIComponent(url)\n const encodedExcerpt = encodeURIComponent(excerpt || '')\n\n const shareLinks = {\n linkedin: `https://www.linkedin.com/sharing/share-offsite/?url=${encodedUrl}`,\n facebook: `https://www.facebook.com/sharer/sharer.php?u=${encodedUrl}`,\n twitter: `https://twitter.com/intent/tweet?text=${encodedTitle}&url=${encodedUrl}`,\n reddit: `https://reddit.com/submit?url=${encodedUrl}&title=${encodedTitle}`,\n email: `mailto:?subject=${encodedTitle}&body=${encodedExcerpt}%0A%0A${encodedUrl}`,\n whatsapp: `https://wa.me/?text=${encodedTitle}%20${encodedUrl}`,\n telegram: `https://t.me/share/url?url=${encodedUrl}&text=${encodedTitle}`,\n }\n\n const copyToClipboard = async () => {\n try {\n await navigator.clipboard.writeText(url)\n setCopied(true)\n setTimeout(() => setCopied(false), 2000)\n } catch {\n // clipboard unavailable\n }\n }\n\n const openShareWindow = (shareUrl: string) => {\n globalThis.open(shareUrl, '_blank', 'width=600,height=400,scrollbars=yes,resizable=yes')\n }\n\n const btnClass =\n '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'\n\n return (\n <div className=\"border-t border-border pt-8 mt-8\">\n <div className=\"flex items-center gap-2 mb-4\">\n <Share2 className=\"h-5 w-5 text-muted-foreground\" />\n <h3 className=\"text-lg font-semibold text-foreground\">Share this article</h3>\n </div>\n\n <div className=\"flex flex-wrap gap-2\">\n <button className={btnClass} onClick={() => openShareWindow(shareLinks.linkedin)}>\n <Users className=\"h-4 w-4\" />\n LinkedIn\n </button>\n <button className={btnClass} onClick={() => openShareWindow(shareLinks.facebook)}>\n <span className=\"text-xs font-bold\">f</span> Facebook\n </button>\n <button className={btnClass} onClick={() => openShareWindow(shareLinks.twitter)}>\n <MessageCircle className=\"h-4 w-4\" />\n Twitter\n </button>\n <button className={btnClass} onClick={() => openShareWindow(shareLinks.reddit)}>\n <FileText className=\"h-4 w-4\" />\n Reddit\n </button>\n <button className={btnClass} onClick={() => openShareWindow(shareLinks.whatsapp)}>\n <MessageCircle className=\"h-4 w-4\" />\n WhatsApp\n </button>\n <button className={btnClass} onClick={() => openShareWindow(shareLinks.telegram)}>\n <MessageCircle className=\"h-4 w-4\" />\n Telegram\n </button>\n <a className={btnClass} href={shareLinks.email}>\n <Mail className=\"h-4 w-4\" />\n Email\n </a>\n <button className={btnClass} onClick={copyToClipboard}>\n {copied ? <Check className=\"h-4 w-4\" /> : <Copy className=\"h-4 w-4\" />}\n {copied ? 'Copied!' : 'Copy Link'}\n </button>\n </div>\n\n {shareMessage && <p className=\"text-sm text-muted-foreground mt-3\">{shareMessage}</p>}\n </div>\n )\n}\n","import Link from 'next/link'\nimport { ChevronLeft, ChevronRight } from 'lucide-react'\n\ninterface ArticleNavigationProps {\n readonly previous: { slug: string; title: string } | null\n readonly next: { slug: string; title: string } | null\n readonly basePath: string\n}\n\nfunction truncateTitle(title: string, maxLength = 60): string {\n return title.length > maxLength ? `${title.substring(0, maxLength)}...` : title\n}\n\nexport function ArticleNavigation({ previous, next, basePath }: ArticleNavigationProps) {\n if (!previous && !next) return null\n\n return (\n <nav className=\"mt-12 pt-8 border-t border-border\" aria-label=\"Article navigation\">\n <div className=\"flex justify-between gap-4\">\n <div className=\"flex-1 min-w-0\">\n {previous && (\n <Link\n href={`${basePath}/${previous.slug}`}\n className=\"group flex items-center gap-3 p-4 rounded-lg border border-border hover:border-primary/20 hover:bg-muted/50 transition-colors\"\n >\n <ChevronLeft className=\"h-5 w-5 text-muted-foreground group-hover:text-primary shrink-0\" />\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-sm text-muted-foreground mb-1\">Previous Article</div>\n <div className=\"font-medium text-foreground truncate\" title={previous.title}>\n {truncateTitle(previous.title)}\n </div>\n </div>\n </Link>\n )}\n </div>\n\n <div className=\"flex-1 min-w-0\">\n {next && (\n <Link\n href={`${basePath}/${next.slug}`}\n 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\"\n >\n <div className=\"min-w-0 flex-1 text-right\">\n <div className=\"text-sm text-muted-foreground mb-1\">Next Article</div>\n <div className=\"font-medium text-foreground truncate\" title={next.title}>\n {truncateTitle(next.title)}\n </div>\n </div>\n <ChevronRight className=\"h-5 w-5 text-muted-foreground group-hover:text-primary shrink-0\" />\n </Link>\n )}\n </div>\n </div>\n </nav>\n )\n}\n","import Link from 'next/link'\nimport { ArrowLeft } from 'lucide-react'\nimport type { ArticlesConfig } from './articlesConfig'\n\ntype ArticleBackLinkProps = Readonly<{\n config: Pick<ArticlesConfig, 'showBackToArticles'>\n href?: string\n label?: string\n className?: string\n}>\n\nexport function ArticleBackLink({\n config,\n href = '/articles',\n label = 'Back to Articles',\n className,\n}: ArticleBackLinkProps) {\n if (config.showBackToArticles === false) return null\n\n return (\n <Link\n href={href}\n className={\n className ??\n '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'\n }\n >\n <ArrowLeft className=\"h-4 w-4\" />\n {label}\n </Link>\n )\n}\n","import type { TocItem } from './articleTypes'\n\ntype ArticleTOCProps = Readonly<{ toc: TocItem[]; className?: string }>\n\nexport function ArticleTOC({ toc, className }: ArticleTOCProps) {\n if (!toc.length) return null\n return (\n <nav\n aria-label=\"Table of contents\"\n className={`mb-8 rounded-lg border border-border bg-muted/40 px-6 py-4 ${className ?? ''}`}\n >\n <p className=\"mb-3 text-sm font-semibold uppercase tracking-wide text-muted-foreground\">\n On this page\n </p>\n <ul className=\"space-y-1 text-sm\">\n {toc.map((item) => (\n <li key={item.id} style={{ paddingLeft: `${Math.max(0, item.depth - 2) * 1}rem` }}>\n <a\n href={`#${item.id}`}\n className=\"text-muted-foreground hover:text-foreground transition-colors\"\n >\n {item.text}\n </a>\n </li>\n ))}\n </ul>\n </nav>\n )\n}\n","'use client'\nimport { useEffect, useState } from 'react'\nimport { ArrowUp } from 'lucide-react'\n\nexport function ScrollToTop() {\n const [visible, setVisible] = useState(false)\n\n useEffect(() => {\n const onScroll = () => setVisible(globalThis.scrollY > 300)\n globalThis.addEventListener('scroll', onScroll, { passive: true })\n return () => globalThis.removeEventListener('scroll', onScroll)\n }, [])\n\n if (!visible) return null\n\n return (\n <button\n aria-label=\"Scroll to top\"\n onClick={() => globalThis.scrollTo({ top: 0, behavior: 'smooth' })}\n 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\"\n >\n <ArrowUp className=\"h-5 w-5\" />\n </button>\n )\n}\n","'use client'\n\nimport { useSession, signIn } from 'next-auth/react'\nimport { useCallback, useEffect, useState } from 'react'\nimport { CommentForm } from './CommentForm'\nimport { CommentThread } from './CommentThread'\nimport type { CommentsConfig } from './articlesConfig'\nimport type { ArticleCommentWithReplies } from './commentTypes'\n\ninterface CommentsSectionProps {\n readonly articleSlug: string\n readonly config: CommentsConfig\n}\n\nexport function CommentsSection({ articleSlug, config }: CommentsSectionProps) {\n const { data: session, status } = useSession()\n const [comments, setComments] = useState<ArticleCommentWithReplies[]>([])\n const [loading, setLoading] = useState(true)\n const [fetchError, setFetchError] = useState<string | null>(null)\n\n const perArticleEnabled = config.perArticleOverride?.[articleSlug] ?? true\n const enabled = config.enabled && perArticleEnabled\n\n const currentUserId = session?.user?.email ?? session?.user?.name ?? undefined\n\n const fetchComments = useCallback(async () => {\n setLoading(true)\n setFetchError(null)\n try {\n const res = await fetch(`/api/articles/${articleSlug}/comments`)\n if (!res.ok) throw new Error('Failed to load comments')\n const data = (await res.json()) as { comments: ArticleCommentWithReplies[] }\n setComments(data.comments)\n } catch {\n setFetchError('Could not load comments. Please try again.')\n } finally {\n setLoading(false)\n }\n }, [articleSlug])\n\n useEffect(() => {\n if (enabled) {\n fetchComments().catch(() => undefined)\n }\n }, [fetchComments, enabled])\n\n if (!enabled) return null\n\n const count = comments.length\n const label = count === 1 ? '1 comment' : `${count} comments`\n\n return (\n <section aria-label=\"Comments\" className=\"mt-12 pt-8 border-t border-border space-y-6\">\n <h2 className=\"text-xl font-semibold text-foreground\">{loading ? 'Comments' : label}</h2>\n\n {status === 'authenticated' ? (\n <CommentForm articleSlug={articleSlug} onSuccess={fetchComments} />\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n <button\n onClick={() => signIn()}\n className=\"text-primary underline hover:no-underline focus:outline-none\"\n >\n Sign in\n </button>{' '}\n to join the discussion.\n </p>\n )}\n\n {fetchError && <p className=\"text-sm text-destructive\">{fetchError}</p>}\n\n {loading ? (\n <p className=\"text-sm text-muted-foreground\">Loading comments…</p>\n ) : (\n <CommentThread\n comments={comments}\n articleSlug={articleSlug}\n currentUserId={currentUserId}\n onRefresh={fetchComments}\n />\n )}\n </section>\n )\n}\n","'use client'\n\nimport { useState } from 'react'\n\nconst MAX_LENGTH = 2000\nconst WARN_THRESHOLD = 1800\n\nfunction submitLabel(submitting: boolean, parentId?: string): string {\n if (submitting) return 'Posting…'\n return parentId ? 'Reply' : 'Post comment'\n}\n\ninterface CommentFormProps {\n readonly articleSlug: string\n readonly parentId?: string\n readonly onSuccess: () => void\n readonly onCancel?: () => void\n}\n\nexport function CommentForm({ articleSlug, parentId, onSuccess, onCancel }: CommentFormProps) {\n const [body, setBody] = useState('')\n const [submitting, setSubmitting] = useState(false)\n const [error, setError] = useState<string | null>(null)\n\n const remaining = MAX_LENGTH - body.length\n\n async function handleSubmit(e: React.FormEvent) {\n e.preventDefault()\n if (!body.trim() || submitting) return\n\n setSubmitting(true)\n setError(null)\n\n try {\n const res = await fetch(`/api/articles/${articleSlug}/comments`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ body: body.trim(), parentId: parentId ?? null }),\n })\n\n if (!res.ok) {\n const data = (await res.json()) as { error?: string }\n setError(data.error ?? 'Failed to post comment')\n return\n }\n\n setBody('')\n onSuccess()\n } catch {\n setError('Network error — please try again')\n } finally {\n setSubmitting(false)\n }\n }\n\n return (\n <form onSubmit={handleSubmit} className=\"space-y-2\">\n <textarea\n value={body}\n onChange={(e) => setBody(e.target.value)}\n maxLength={MAX_LENGTH}\n rows={parentId ? 3 : 4}\n placeholder={parentId ? 'Write a reply…' : 'Join the discussion…'}\n disabled={submitting}\n className=\"w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/50 disabled:opacity-50 resize-none\"\n aria-label={parentId ? 'Reply text' : 'Comment text'}\n />\n\n {remaining <= MAX_LENGTH - WARN_THRESHOLD && (\n <p className={`text-xs ${remaining < 0 ? 'text-destructive' : 'text-muted-foreground'}`}>\n {remaining} characters remaining\n </p>\n )}\n\n {error && <p className=\"text-xs text-destructive\">{error}</p>}\n\n <div className=\"flex gap-2\">\n <button\n type=\"submit\"\n disabled={submitting || body.trim().length === 0 || body.length > MAX_LENGTH}\n className=\"rounded-md bg-primary px-4 py-1.5 text-sm font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n {submitLabel(submitting, parentId)}\n </button>\n\n {onCancel && (\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"rounded-md px-4 py-1.5 text-sm font-medium text-muted-foreground hover:text-foreground\"\n >\n Cancel\n </button>\n )}\n </div>\n </form>\n )\n}\n","'use client'\n\nimport { useState } from 'react'\nimport { CommentForm } from './CommentForm'\nimport type { ArticleComment, ArticleCommentWithReplies } from './commentTypes'\n\nfunction relativeTime(iso: string): string {\n const diff = Date.now() - new Date(iso).getTime()\n const minutes = Math.floor(diff / 60_000)\n if (minutes < 1) return 'just now'\n if (minutes < 60) return `${minutes}m ago`\n const hours = Math.floor(minutes / 60)\n if (hours < 24) return `${hours}h ago`\n const days = Math.floor(hours / 24)\n if (days < 30) return `${days}d ago`\n const months = Math.floor(days / 30)\n if (months < 12) return `${months}mo ago`\n return `${Math.floor(months / 12)}y ago`\n}\n\ninterface CommentItemProps {\n readonly comment: ArticleCommentWithReplies | ArticleComment\n readonly articleSlug: string\n readonly currentUserId?: string\n readonly isReply?: boolean\n readonly onRefresh: () => void\n}\n\nexport function CommentItem({\n comment,\n articleSlug,\n currentUserId,\n isReply = false,\n onRefresh,\n}: CommentItemProps) {\n const [showReplyForm, setShowReplyForm] = useState(false)\n const [deleting, setDeleting] = useState(false)\n\n const replies = 'replies' in comment ? comment.replies : []\n const canReply = !isReply && !!currentUserId && !comment.isDeleted\n const canDelete = !!currentUserId && currentUserId === comment.authorId && !comment.isDeleted\n\n async function handleDelete() {\n if (deleting) return\n setDeleting(true)\n try {\n await fetch(`/api/articles/${articleSlug}/comments/${comment.id}`, { method: 'DELETE' })\n onRefresh()\n } finally {\n setDeleting(false)\n }\n }\n\n return (\n <div className={`${isReply ? 'ml-8 border-l-2 border-border pl-4' : ''}`}>\n <div className=\"rounded-lg bg-muted/40 p-3 space-y-1\">\n {comment.isDeleted ? (\n <p className=\"text-sm italic text-muted-foreground\">Comment removed</p>\n ) : (\n <>\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"text-sm font-medium text-foreground\">{comment.authorName}</span>\n <span className=\"text-xs text-muted-foreground\">\n {relativeTime(comment.createdAt)}\n </span>\n </div>\n <p className=\"text-sm text-foreground whitespace-pre-wrap break-words\">\n {comment.body}\n </p>\n <div className=\"flex gap-3 pt-1\">\n {canReply && (\n <button\n onClick={() => setShowReplyForm((v) => !v)}\n className=\"text-xs text-muted-foreground hover:text-foreground\"\n >\n {showReplyForm ? 'Cancel' : 'Reply'}\n </button>\n )}\n {canDelete && (\n <button\n onClick={handleDelete}\n disabled={deleting}\n className=\"text-xs text-muted-foreground hover:text-destructive disabled:opacity-50\"\n >\n {deleting ? 'Deleting…' : 'Delete'}\n </button>\n )}\n </div>\n </>\n )}\n </div>\n\n {showReplyForm && (\n <div className=\"mt-2 ml-2\">\n <CommentForm\n articleSlug={articleSlug}\n parentId={comment.id}\n onSuccess={() => {\n setShowReplyForm(false)\n onRefresh()\n }}\n onCancel={() => setShowReplyForm(false)}\n />\n </div>\n )}\n\n {replies.length > 0 && (\n <div className=\"mt-2 space-y-2\">\n {replies.map((reply) => (\n <CommentItem\n key={reply.id}\n comment={{ ...reply, replies: [] }}\n articleSlug={articleSlug}\n currentUserId={currentUserId}\n isReply\n onRefresh={onRefresh}\n />\n ))}\n </div>\n )}\n </div>\n )\n}\n","'use client'\n\nimport { CommentItem } from './CommentItem'\nimport type { ArticleCommentWithReplies } from './commentTypes'\n\ninterface CommentThreadProps {\n readonly comments: ArticleCommentWithReplies[]\n readonly articleSlug: string\n readonly currentUserId?: string\n readonly onRefresh: () => void\n}\n\nexport function CommentThread({\n comments,\n articleSlug,\n currentUserId,\n onRefresh,\n}: CommentThreadProps) {\n if (comments.length === 0) {\n return (\n <p className=\"text-sm text-muted-foreground text-center py-6\">\n No comments yet. Be the first to share your thoughts.\n </p>\n )\n }\n\n return (\n <div className=\"space-y-4\">\n {comments.map((comment) => (\n <CommentItem\n key={comment.id}\n comment={comment}\n articleSlug={articleSlug}\n currentUserId={currentUserId}\n onRefresh={onRefresh}\n />\n ))}\n </div>\n )\n}\n"],"mappings":"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","names":["jsx","jsxs","jsx","jsxs","Link","jsx","jsxs","Link","Image","jsx","jsxs","Search","useState","useEffect","Image","Link","ArrowRight","Calendar","Clock","jsx","jsxs","jsx","jsxs","useState","useEffect","jsx","jsxs","Search","useState","useEffect","useState","useEffect","jsx","jsxs","Image","Link","Calendar","Clock","User","jsx","jsxs","Image","Link","jsx","jsxs","Image","Link","useState","jsx","jsxs","useState","Link","jsx","jsxs","Link","jsx","jsxs","jsx","jsxs","useEffect","useState","jsx","useCallback","useEffect","useState","useState","jsx","jsxs","useState","e","useState","Fragment","jsx","jsxs","useState","jsx","jsx","jsxs","useState","useCallback","useEffect"]}
1
+ {"version":3,"sources":["../src/ArticleCategoryGrid.tsx","../src/ArticleSchemas.tsx","../src/ArticleSearchBar.tsx","../src/ArticlesHero.tsx","../src/FeaturedArticle.tsx","../src/LatestArticlesSection.tsx","../src/LatestArticles.tsx","../src/ArticleCard.tsx","../src/articlesConfig.ts","../src/useArticles.ts","../src/ArticlesPage.tsx","../src/ArticleDetailHero.tsx","../src/CategoryArticlesPage.tsx","../src/ArticleSocialShare.tsx","../src/ArticleNavigation.tsx","../src/ArticleBackLink.tsx","../src/ArticleTOC.tsx","../src/ScrollToTop.tsx","../src/CommentsSection.tsx","../src/CommentForm.tsx","../src/CommentItem.tsx","../src/CommentThread.tsx"],"sourcesContent":["'use client'\n\nimport Image from 'next/image'\nimport Link from 'next/link'\nimport { useState, useEffect } from 'react'\nimport type { CategoryInfo } from './articleTypes'\n\ntype ArticleCategoryGridProps = Readonly<{\n categories: CategoryInfo[]\n pageSize?: number\n}>\n\nexport function ArticleCategoryGrid({ categories, pageSize = 8 }: ArticleCategoryGridProps) {\n const [visibleCount, setVisibleCount] = useState(pageSize)\n\n useEffect(() => {\n setVisibleCount(pageSize)\n }, [categories, pageSize])\n\n if (categories.length === 0) return null\n\n const visible = categories.slice(0, visibleCount)\n const hasMore = visibleCount < categories.length\n\n return (\n <section className=\"py-16 bg-background\">\n <div className=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8\">\n <div className=\"text-center mb-12\">\n <h2 className=\"text-3xl font-bold text-foreground mb-4\">Browse by Category</h2>\n <p className=\"text-lg text-muted-foreground\">\n Explore our articles by topic to find the insights most relevant to your interests.\n </p>\n </div>\n\n <div className=\"grid md:grid-cols-2 lg:grid-cols-3 gap-6\">\n {visible.map((cat) => (\n <Link key={cat.slug} href={`/articles/category/${cat.slug}`}>\n <div className=\"group overflow-hidden rounded-xl border border-border shadow-sm hover:shadow-lg transition-all duration-300 cursor-pointer bg-card\">\n <div className=\"overflow-hidden\" style={{ position: 'relative', height: '13rem' }}>\n <Image\n src={cat.featuredImage}\n alt={cat.name}\n fill\n sizes=\"(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw\"\n className=\"object-cover group-hover:scale-105 transition-transform duration-300\"\n />\n </div>\n <div className=\"p-4 text-center\">\n <h3 className=\"font-semibold text-foreground text-base\">{cat.name}</h3>\n <p className=\"text-sm text-muted-foreground mt-1\">\n {cat.count} {cat.count === 1 ? 'article' : 'articles'}\n </p>\n </div>\n </div>\n </Link>\n ))}\n </div>\n\n {hasMore && (\n <div className=\"mt-10 text-center\">\n <button\n type=\"button\"\n onClick={() => setVisibleCount((c) => c + pageSize)}\n className=\"inline-flex items-center justify-center px-4 py-2 border border-input bg-background hover:bg-accent rounded-md font-medium text-sm transition-colors\"\n >\n Load more categories\n </button>\n </div>\n )}\n </div>\n </section>\n )\n}\n","import { Article, FaqItem, HowToStep } from './articleTypes'\n\ntype ArticleSchemaProps = Readonly<{\n article: Article\n articleUrl: string\n siteName: string\n showAuthor?: boolean\n}>\n\nexport function ArticleSchema({\n article,\n articleUrl,\n siteName,\n showAuthor = true,\n}: ArticleSchemaProps) {\n const schema = {\n '@context': 'https://schema.org',\n '@type': 'Article',\n headline: article.title,\n description: article.excerpt,\n image: article.featuredImage,\n ...(article.date && { datePublished: new Date(article.date).toISOString() }),\n ...(showAuthor && { author: { '@type': 'Person', name: article.author } }),\n publisher: { '@type': 'Organization', name: siteName },\n mainEntityOfPage: { '@type': 'WebPage', '@id': articleUrl },\n }\n\n return (\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}\n />\n )\n}\n\ntype BreadcrumbSchemaProps = Readonly<{\n items: ReadonlyArray<{ name: string; url: string }>\n}>\n\nexport function BreadcrumbSchema({ items }: BreadcrumbSchemaProps) {\n const schema = {\n '@context': 'https://schema.org',\n '@type': 'BreadcrumbList',\n itemListElement: items.map((item, index) => ({\n '@type': 'ListItem',\n position: index + 1,\n name: item.name,\n item: item.url,\n })),\n }\n\n return (\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}\n />\n )\n}\n\ntype ArticleSEOProps = Readonly<{\n article: Article\n articleUrl: string\n siteName: string\n siteLogo?: string\n showAuthor?: boolean\n}>\n\nexport function ArticleSEO({\n article,\n articleUrl,\n siteName,\n siteLogo,\n showAuthor = true,\n}: ArticleSEOProps) {\n const publishedAt = article.date ? new Date(article.date).toISOString() : undefined\n const modifiedAt = article.lastmod ? new Date(article.lastmod).toISOString() : publishedAt\n\n const structuredData = {\n '@context': 'https://schema.org',\n '@type': article.articleType || 'Article',\n mainEntityOfPage: { '@type': 'WebPage', '@id': articleUrl },\n headline: article.title,\n image: article.featuredImage\n ? { '@type': 'ImageObject', url: article.featuredImage }\n : undefined,\n ...(publishedAt && { datePublished: publishedAt }),\n ...(modifiedAt && { dateModified: modifiedAt }),\n ...(showAuthor && { author: { '@type': 'Person', name: article.author } }),\n publisher: {\n '@type': 'Organization',\n name: siteName,\n ...(siteLogo && { logo: { '@type': 'ImageObject', url: siteLogo } }),\n },\n description: article.excerpt,\n ...(article.series && { isPartOf: { '@type': 'Blog', name: article.series } }),\n }\n\n return (\n <>\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{ __html: JSON.stringify(structuredData) }}\n />\n {article.faq && article.faq.length > 0 && (\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{\n __html: JSON.stringify({\n '@context': 'https://schema.org',\n '@type': 'FAQPage',\n mainEntity: article.faq.map(({ question, answer }: FaqItem) => ({\n '@type': 'Question',\n name: question,\n acceptedAnswer: { '@type': 'Answer', text: answer },\n })),\n }),\n }}\n />\n )}\n {article.howTo && article.howTo.length > 0 && (\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{\n __html: JSON.stringify({\n '@context': 'https://schema.org',\n '@type': 'HowTo',\n name: article.title,\n step: article.howTo.map(({ name, text }: HowToStep) => ({\n '@type': 'HowToStep',\n name,\n text,\n })),\n }),\n }}\n />\n )}\n </>\n )\n}\n\ntype FAQPageSchemaProps = Readonly<{\n items: ReadonlyArray<{ question: string; answer: string }>\n}>\n\nexport function FAQPageSchema({ items }: FAQPageSchemaProps) {\n const schema = {\n '@context': 'https://schema.org',\n '@type': 'FAQPage',\n mainEntity: items.map(({ question, answer }) => ({\n '@type': 'Question',\n name: question,\n acceptedAnswer: { '@type': 'Answer', text: answer },\n })),\n }\n return (\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}\n />\n )\n}\n\ntype CollectionPageSchemaProps = Readonly<{\n title: string\n description: string\n url: string\n articleCount: number\n}>\n\nexport function CollectionPageSchema({\n title,\n description,\n url,\n articleCount,\n}: CollectionPageSchemaProps) {\n const schema = {\n '@context': 'https://schema.org',\n '@type': 'CollectionPage',\n name: title,\n description,\n url,\n numberOfItems: articleCount,\n }\n\n return (\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}\n />\n )\n}\n","import { Search, X } from 'lucide-react'\n\ntype ArticleSearchBarProps = Readonly<{\n value: string\n onChange: (query: string) => void\n disabled?: boolean\n resultCount?: number\n}>\n\nexport function ArticleSearchBar({\n value,\n onChange,\n disabled,\n resultCount,\n}: ArticleSearchBarProps) {\n return (\n <section className=\"py-8 bg-background border-b border-border\">\n <div className=\"max-w-4xl mx-auto px-4 sm:px-6 lg:px-8\">\n <div className=\"relative\">\n <Search className=\"absolute left-3 top-1/2 transform -translate-y-1/2 text-muted-foreground h-5 w-5\" />\n <input\n type=\"text\"\n placeholder=\"Search articles (3+ characters required)...\"\n value={value}\n onChange={(e) => onChange(e.target.value)}\n disabled={disabled}\n 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\"\n />\n {value && (\n <button\n type=\"button\"\n onClick={() => onChange('')}\n aria-label=\"Clear search\"\n className=\"absolute right-3 top-1/2 transform -translate-y-1/2 text-muted-foreground hover:text-foreground\"\n >\n <X className=\"h-5 w-5\" />\n </button>\n )}\n </div>\n {value && (\n <div className=\"mt-2 text-sm text-muted-foreground\">\n {resultCount === 0\n ? 'No articles found matching your search.'\n : `Found ${resultCount} article${resultCount === 1 ? '' : 's'} matching \"${value}\"`}\n </div>\n )}\n </div>\n </section>\n )\n}\n","import Link from 'next/link'\n\nconst DEFAULT_TITLE = 'Vox Populus Insights'\nconst DEFAULT_DESCRIPTION =\n 'Expert analysis, campaign strategies, and voter engagement insights from the frontlines of democracy.'\n\ntype ArticlesHeroProps = Readonly<{\n title?: string\n description?: string\n}>\n\nexport function ArticlesHero({\n title = DEFAULT_TITLE,\n description = DEFAULT_DESCRIPTION,\n}: ArticlesHeroProps) {\n return (\n <section className=\"bg-linear-to-r from-gray-50 to-gray-100 py-16 md:py-24\">\n <div className=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8\">\n <div className=\"max-w-3xl mx-auto text-center\">\n <h1 className=\"text-4xl md:text-5xl font-bold text-foreground mb-6\">{title}</h1>\n <p className=\"text-xl text-muted-foreground mb-8\">{description}</p>\n <div className=\"flex flex-col sm:flex-row gap-4 justify-center\">\n <Link\n href=\"#latest\"\n 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\"\n >\n Browse Latest Articles\n </Link>\n <Link\n href=\"/contact\"\n 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\"\n >\n Contact Our Team\n </Link>\n </div>\n </div>\n </div>\n </section>\n )\n}\n","import Link from 'next/link'\nimport Image from 'next/image'\nimport { ArrowRight, Calendar, Clock, User } from 'lucide-react'\nimport type { Article } from './articleTypes'\n\ntype FeaturedArticleProps = Readonly<{\n article: Article\n showAuthor?: boolean\n}>\n\nexport function FeaturedArticle({ article, showAuthor = true }: FeaturedArticleProps) {\n return (\n <section className=\"py-16 bg-background\">\n <div className=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8\">\n <div className=\"grid lg:grid-cols-2 gap-12 items-center\">\n <div>\n <span className=\"inline-block bg-primary/10 text-primary text-sm font-medium px-3 py-1 rounded-full mb-4\">\n FEATURED ARTICLE\n </span>\n <h2 className=\"text-3xl font-bold text-foreground mb-4\">{article.title}</h2>\n <p className=\"text-lg text-muted-foreground mb-6\">{article.excerpt}</p>\n <div className=\"flex items-center gap-6 text-sm text-muted-foreground mb-6\">\n {article.date && (\n <div className=\"flex items-center gap-2\">\n <Calendar className=\"h-4 w-4\" />\n <span>{article.date}</span>\n </div>\n )}\n <div className=\"flex items-center gap-2\">\n <Clock className=\"h-4 w-4\" />\n <span>{article.readTime}</span>\n </div>\n {showAuthor && (\n <div className=\"flex items-center gap-2\">\n <User className=\"h-4 w-4\" />\n <span>{article.author}</span>\n </div>\n )}\n </div>\n <Link\n href={`/articles/${article.slug}`}\n 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\"\n >\n Read Full Article\n <ArrowRight className=\"ml-2 h-4 w-4\" />\n </Link>\n </div>\n <div className=\"bg-card rounded-lg p-8\">\n <Image\n src={article.featuredImage}\n alt={article.title}\n width={800}\n height={450}\n className=\"w-full h-64 object-cover rounded-lg mb-4\"\n />\n <div className=\"flex gap-2\">\n <span className=\"bg-primary/10 text-primary text-xs font-medium px-2 py-1 rounded\">\n {article.category}\n </span>\n </div>\n </div>\n </div>\n </div>\n </section>\n )\n}\n","'use client'\n\nimport { Search } from 'lucide-react'\nimport type { Article } from './articleTypes'\nimport { LatestArticles } from './LatestArticles'\n\ninterface LatestArticlesSectionProps {\n readonly articles: Article[]\n readonly searchQuery: string\n readonly onClearSearch: () => void\n readonly pageSize?: number\n}\n\nfunction DescriptionText({\n searchQuery,\n count,\n}: {\n readonly searchQuery: string\n readonly count: number\n}) {\n const pluralSuffix = count === 1 ? '' : 's'\n const text = searchQuery\n ? `Found ${count} article${pluralSuffix} matching your search.`\n : 'Stay informed with our latest insights on voter engagement, campaign strategies, and civic technology.'\n return <p className=\"text-lg text-muted-foreground\">{text}</p>\n}\n\nexport function LatestArticlesSection({\n articles,\n searchQuery,\n onClearSearch,\n pageSize = 6,\n}: Readonly<LatestArticlesSectionProps>) {\n return (\n <section id=\"latest\" className=\"py-16 bg-muted/50\">\n <div className=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8\">\n <div className=\"text-center mb-12\">\n <h2 className=\"text-3xl font-bold text-foreground mb-4\">\n {searchQuery ? 'Search Results' : 'Latest Articles'}\n </h2>\n <DescriptionText searchQuery={searchQuery} count={articles.length} />\n </div>\n\n {articles.length === 0 && searchQuery ? (\n <div className=\"text-center py-12\">\n <div className=\"max-w-md mx-auto\">\n <Search className=\"h-12 w-12 text-muted-foreground mx-auto mb-4\" />\n <h3 className=\"text-lg font-semibold text-foreground mb-2\">No articles found</h3>\n <p className=\"text-muted-foreground mb-4\">\n We couldn&apos;t find any articles matching &quot;{searchQuery}&quot;. Try adjusting\n your search terms.\n </p>\n <button\n type=\"button\"\n onClick={onClearSearch}\n className=\"inline-flex items-center justify-center px-4 py-2 border border-input bg-background hover:bg-accent rounded-md font-medium text-sm transition-colors\"\n >\n Clear search\n </button>\n </div>\n </div>\n ) : (\n <LatestArticles articles={articles} pageSize={pageSize} key={searchQuery} />\n )}\n </div>\n </section>\n )\n}\n","'use client'\n\nimport { useState, useEffect } from 'react'\nimport type { Article } from './articleTypes'\nimport { ArticleCard } from './ArticleCard'\n\ninterface LatestArticlesProps {\n readonly articles: Article[]\n readonly pageSize: number\n}\n\nexport function LatestArticles({ articles, pageSize }: Readonly<LatestArticlesProps>) {\n const [visibleCount, setVisibleCount] = useState(pageSize)\n\n useEffect(() => {\n setVisibleCount(pageSize)\n }, [articles, pageSize])\n\n const visible = articles.slice(0, visibleCount)\n const hasMore = visibleCount < articles.length\n\n return (\n <div>\n <div className=\"grid md:grid-cols-2 lg:grid-cols-3 gap-8\">\n {visible.map((article) => (\n <ArticleCard key={article.slug} article={article} />\n ))}\n </div>\n {hasMore && (\n <div className=\"mt-10 text-center\">\n <button\n type=\"button\"\n onClick={() => setVisibleCount((c) => c + pageSize)}\n className=\"inline-flex items-center justify-center px-4 py-2 border border-input bg-background hover:bg-accent rounded-md font-medium text-sm transition-colors\"\n >\n Load more articles\n </button>\n </div>\n )}\n </div>\n )\n}\n","'use client'\n\nimport Image from 'next/image'\nimport Link from 'next/link'\nimport { ArrowRight, Calendar, Clock } from 'lucide-react'\nimport type { Article } from './articleTypes'\n\ntype ArticleCardProps = Readonly<{\n article: Article\n}>\n\nexport function ArticleCard({ article }: ArticleCardProps) {\n return (\n <div className=\"rounded-lg border border-border bg-card text-card-foreground shadow-sm hover:shadow-lg transition-shadow duration-300\">\n <div className=\"p-0\">\n <Image\n src={article.featuredImage}\n alt={article.title}\n className=\"w-full h-48 object-cover rounded-t-lg\"\n width={400}\n height={200}\n />\n </div>\n <div className=\"p-6\">\n <div className=\"flex gap-2 mb-3\">\n <span className=\"bg-primary/10 text-primary text-xs font-medium px-2 py-1 rounded\">\n {article.category}\n </span>\n </div>\n <h3 className=\"text-lg font-semibold leading-none tracking-tight mb-2\">\n <Link\n href={`/articles/${article.slug}`}\n className=\"hover:text-indigo-600 transition-colors\"\n >\n {article.title}\n </Link>\n </h3>\n <p className=\"text-muted-foreground mb-4 line-clamp-3\">{article.excerpt}</p>\n <div className=\"flex items-center justify-between text-sm text-muted-foreground border-t pt-4\">\n <div className=\"flex items-center gap-3\">\n {article.date && (\n <div className=\"flex items-center gap-2\">\n <Calendar className=\"h-3 w-3\" />\n <span>{article.date}</span>\n </div>\n )}\n <div className=\"flex items-center gap-2\">\n <Clock className=\"h-3 w-3\" />\n <span>{article.readTime}</span>\n </div>\n </div>\n <Link\n href={`/articles/${article.slug}`}\n className=\"inline-flex items-center justify-center h-8 w-8 p-0 rounded-md hover:bg-accent transition-colors\"\n aria-label={`Read ${article.title}`}\n >\n <ArrowRight className=\"h-4 w-4\" />\n </Link>\n </div>\n </div>\n </div>\n )\n}\n","/** Keys for each renderable section of the articles listing page. */\nexport type ArticlesSection =\n | 'hero'\n | 'search'\n | 'featured'\n | 'latest'\n | 'categories'\n | 'newsletter'\n\n/**\n * CSS custom-property overrides applied to the library's wrapper div.\n * All fields are optional; omitted fields fall back to the consuming app's Tailwind theme.\n */\nexport interface ArticlesTheme {\n /** Font family for the articles section. Example: `\"'Inter', sans-serif\"` */\n fontFamily?: string\n /** Color for article card titles and section headings. Example: `'#111827'` */\n headerColor?: string\n /** Color for body and excerpt text. Example: `'#6b7280'` */\n textColor?: string\n /** Background color for sections and cards. Example: `'#ffffff'` */\n backgroundColor?: string\n /** Color for \"Read More\" links and inline links. Example: `'#4f46e5'` */\n linkColor?: string\n /** Hover color for links. Example: `'#4338ca'` */\n linkHoverColor?: string\n /** Text decoration for links. Values: `'underline'` | `'none'` */\n linkTextDecoration?: string\n /** Font weight for headings. Example: `700` */\n headerFontWeight?: string | number\n /** Font size for article card titles. Example: `'1.25rem'` */\n headerFontSize?: string\n /** Font size for body text. Example: `'1rem'` */\n bodyFontSize?: string\n /** Line height for body text. Example: `'1.75'` */\n lineHeight?: string\n /** Border radius for cards. Example: `'0.5rem'` */\n borderRadius?: string\n}\n\n/** Per-category text used in meta descriptions and on the category hero page. */\nexport interface CategoryDescription {\n /** Short description — used in meta description and category grid card. */\n short: string\n /** Long description — rendered as a hero paragraph on the category page. */\n long?: string\n}\n\n/** Controls the comments feature. Attach to `ArticlesConfig.comments`. */\nexport interface CommentsConfig {\n /** Set to `true` to enable comments globally across all articles. */\n enabled: boolean\n /** Maximum reply nesting depth. Default: `1` (replies to top-level only). */\n maxDepth?: number\n /**\n * Per-article overrides keyed by slug.\n * Example: `{ 'sensitive-article': false }` disables comments on that article only.\n */\n perArticleOverride?: Record<string, boolean>\n}\n\n/** Text content for the hero section at the top of the articles listing page. */\nexport interface HeroConfig {\n /** Main heading displayed in the hero. Default: `'Vox Populus Insights'` */\n title?: string\n /** Subheading paragraph displayed beneath the title. Default: the built-in description. */\n description?: string\n}\n\n/** Top-level configuration object. Pass one instance to every library component. */\nexport interface ArticlesConfig {\n /** Canonical base URL of the site, used in metadata and JSON-LD. Example: `'https://yoursite.com'` */\n siteUrl: string\n /** Site name shown in metadata titles and JSON-LD publisher fields. Example: `'Vox Populus'` */\n siteName: string\n /** Number of articles shown per page in the grid and loaded on each \"Load more\" click. Default: `6` */\n pageSize?: number\n /** Number of category cards shown before a \"Load more categories\" button appears. Default: `8` */\n categoriesPageSize?: number\n /**\n * Ordered list of sections to render on the articles listing page.\n * Omit a key to hide that section entirely. Default: `['hero','search','featured','latest','categories']`\n */\n layout?: ArticlesSection[]\n /** CSS custom-property overrides for colors, fonts, and spacing. All fields optional. */\n theme?: ArticlesTheme\n /**\n * Descriptive text for each category, keyed by category slug.\n * A plain string is treated as the short description only.\n * Example: `{ 'campaigns': { short: 'Campaign tips', long: 'Full paragraph...' } }`\n */\n categoryDescriptions?: Record<string, string | CategoryDescription>\n /** Comments configuration. Omit or set `enabled: false` to hide comments entirely. */\n comments?: CommentsConfig\n /** Hero section title and description. Omit to use the built-in defaults. */\n hero?: HeroConfig\n /** Short description used in the RSS feed channel. Falls back to siteName if omitted. */\n description?: string\n /** Set to false to hide the table of contents on article detail pages. Default: true. */\n showToc?: boolean\n /** Set to false to hide the \"Back to Articles\" navigation link on article detail pages. Default: true. */\n showBackToArticles?: boolean\n /** Set to false to hide author names from UI and metadata. Default: true. */\n showAuthor?: boolean\n}\n\nexport const DEFAULT_PAGE_SIZE = 6\nexport const DEFAULT_CATEGORIES_PAGE_SIZE = 8\n\nexport const DEFAULT_LAYOUT: ArticlesSection[] = [\n 'hero',\n 'search',\n 'featured',\n 'latest',\n 'categories',\n]\n","'use client'\n\nimport { useState, useCallback, useEffect, useRef } from 'react'\nimport { Article, CategoryInfo } from './articleTypes'\n\nexport interface UseArticlesReturn {\n articles: Article[]\n categories: CategoryInfo[]\n searchQuery: string\n loading: boolean\n error: string | null\n handleSearch: (query: string) => void\n}\n\nexport function useArticles(): UseArticlesReturn {\n const [searchQuery, setSearchQuery] = useState('')\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n const [articles, setArticles] = useState<Article[]>([])\n const [categories, setCategories] = useState<CategoryInfo[]>([])\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState<string | null>(null)\n\n const fetchArticles = useCallback(async (query: string) => {\n try {\n setLoading(true)\n const url = query ? `/api/articles?q=${encodeURIComponent(query)}` : '/api/articles'\n const response = await fetch(url)\n\n if (!response.ok) throw new Error('Failed to fetch articles')\n\n const data = await response.json()\n setArticles(data.articles)\n\n if (!query?.trim()) {\n const catMap = new Map<string, { count: number; featuredImage: string }>()\n for (const article of data.articles as Article[]) {\n for (const cat of article.categories) {\n if (!catMap.has(cat)) {\n catMap.set(cat, { count: 0, featuredImage: article.featuredImage })\n }\n catMap.get(cat)!.count++\n }\n }\n setCategories(\n Array.from(catMap.entries())\n .map(([name, { count, featuredImage }]) => ({\n name,\n slug: name\n .toLowerCase()\n .replaceAll(/\\s+/g, '-')\n .replaceAll(/[^a-z0-9-]/g, ''),\n count,\n featuredImage,\n }))\n .sort((a, b) => b.count - a.count)\n )\n }\n\n setError(null)\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to load articles')\n setArticles([])\n } finally {\n setLoading(false)\n }\n }, [])\n\n useEffect(() => {\n fetchArticles('')\n }, [fetchArticles])\n\n const handleSearch = useCallback(\n (query: string) => {\n setSearchQuery(query)\n if (debounceRef.current) clearTimeout(debounceRef.current)\n if (query === '') {\n fetchArticles('')\n } else if (query.length >= 3) {\n debounceRef.current = setTimeout(() => fetchArticles(query), 1000)\n }\n },\n [fetchArticles]\n )\n\n useEffect(\n () => () => {\n if (debounceRef.current) clearTimeout(debounceRef.current)\n },\n []\n )\n\n return { articles, categories, searchQuery, loading, error, handleSearch }\n}\n","'use client'\n\nimport React from 'react'\nimport type { Article, CategoryInfo } from './articleTypes'\nimport { ArticleCategoryGrid } from './ArticleCategoryGrid'\nimport { CollectionPageSchema } from './ArticleSchemas'\nimport { ArticleSearchBar } from './ArticleSearchBar'\nimport { ArticlesHero } from './ArticlesHero'\nimport { FeaturedArticle } from './FeaturedArticle'\nimport { LatestArticlesSection } from './LatestArticlesSection'\nimport {\n ArticlesConfig,\n ArticlesSection,\n ArticlesTheme,\n DEFAULT_CATEGORIES_PAGE_SIZE,\n DEFAULT_LAYOUT,\n DEFAULT_PAGE_SIZE,\n} from './articlesConfig'\nimport { useArticles } from './useArticles'\n\ninterface SectionContext {\n articles: Article[]\n displayedArticles: Article[]\n categories: CategoryInfo[]\n searchQuery: string\n loading: boolean\n error: string | null\n handleSearch: (query: string) => void\n pageSize: number\n categoriesPageSize: number\n}\n\nfunction buildThemeVars(theme?: ArticlesTheme): React.CSSProperties {\n if (!theme) return {}\n const vars: Record<string, string> = {}\n if (theme.fontFamily) vars['--articles-font-family'] = theme.fontFamily\n if (theme.headerColor) vars['--articles-header-color'] = theme.headerColor\n if (theme.textColor) vars['--articles-text-color'] = theme.textColor\n if (theme.backgroundColor) vars['--articles-bg-color'] = theme.backgroundColor\n if (theme.linkColor) vars['--articles-link-color'] = theme.linkColor\n if (theme.linkHoverColor) vars['--articles-link-hover-color'] = theme.linkHoverColor\n if (theme.linkTextDecoration) vars['--articles-link-decoration'] = theme.linkTextDecoration\n if (theme.headerFontWeight) vars['--articles-header-font-weight'] = String(theme.headerFontWeight)\n if (theme.headerFontSize) vars['--articles-header-font-size'] = theme.headerFontSize\n if (theme.bodyFontSize) vars['--articles-body-font-size'] = theme.bodyFontSize\n if (theme.lineHeight) vars['--articles-line-height'] = theme.lineHeight\n if (theme.borderRadius) vars['--articles-border-radius'] = theme.borderRadius\n return vars as React.CSSProperties\n}\n\nfunction renderSection(\n section: ArticlesSection,\n ctx: SectionContext,\n config: ArticlesConfig\n): React.ReactNode {\n const {\n articles,\n displayedArticles,\n categories,\n searchQuery,\n loading,\n error,\n handleSearch,\n pageSize,\n categoriesPageSize,\n } = ctx\n\n switch (section) {\n case 'hero':\n return (\n <ArticlesHero\n key=\"hero\"\n title={config.hero?.title}\n description={config.hero?.description}\n />\n )\n\n case 'search':\n return (\n <ArticleSearchBar\n key=\"search\"\n value={searchQuery}\n onChange={handleSearch}\n disabled={loading}\n resultCount={articles.length}\n />\n )\n\n case 'featured':\n return articles.length > 0 && !searchQuery ? (\n <FeaturedArticle\n key=\"featured\"\n article={articles[0]}\n showAuthor={config.showAuthor !== false}\n />\n ) : null\n\n case 'latest':\n if (loading && articles.length === 0) {\n return (\n <section key=\"latest\" id=\"latest\" className=\"py-16 bg-muted/50 flex-1\">\n <div className=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex items-center justify-center py-24\">\n <div className=\"text-center\">\n <div className=\"animate-spin rounded-full h-12 w-12 border-b-2 border-primary mx-auto mb-4\" />\n <p className=\"text-muted-foreground\">Loading articles...</p>\n </div>\n </div>\n </section>\n )\n }\n if (error) {\n return (\n <section key=\"latest\" id=\"latest\" className=\"py-16 bg-muted/50 flex-1\">\n <div className=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex items-center justify-center\">\n <div className=\"bg-red-50 border border-red-200 rounded-lg p-6 max-w-md text-center\">\n <h3 className=\"text-lg font-semibold text-red-800 mb-2\">Error Loading Articles</h3>\n <p className=\"text-red-600 mb-4\">{error}</p>\n <button\n type=\"button\"\n onClick={() => handleSearch('')}\n className=\"inline-flex items-center justify-center px-4 py-2 border border-input bg-background hover:bg-accent rounded-md font-medium text-sm transition-colors\"\n >\n Try again\n </button>\n </div>\n </div>\n </section>\n )\n }\n return (\n <LatestArticlesSection\n key=\"latest\"\n articles={displayedArticles}\n searchQuery={searchQuery}\n onClearSearch={() => handleSearch('')}\n pageSize={pageSize}\n />\n )\n\n case 'categories':\n return searchQuery ? null : (\n <ArticleCategoryGrid\n key=\"categories\"\n categories={categories}\n pageSize={categoriesPageSize}\n />\n )\n\n // 'newsletter' is intentionally omitted — inject it via the layout prop in the consuming app\n default:\n return null\n }\n}\n\nexport function ArticlesPage({ config }: Readonly<{ config: ArticlesConfig }>) {\n const state = useArticles()\n const layout = config.layout ?? DEFAULT_LAYOUT\n const pageSize = config.pageSize ?? DEFAULT_PAGE_SIZE\n const categoriesPageSize = config.categoriesPageSize ?? DEFAULT_CATEGORIES_PAGE_SIZE\n const themeVars = buildThemeVars(config.theme)\n\n const hasFeatured = layout.includes('featured')\n const articlesWithoutFeatured = hasFeatured ? state.articles.slice(1) : state.articles\n const displayedArticles = state.searchQuery ? state.articles : articlesWithoutFeatured\n\n const ctx: SectionContext = { ...state, displayedArticles, pageSize, categoriesPageSize }\n\n return (\n <div style={themeVars}>\n {layout.map((section) => renderSection(section, ctx, config))}\n {state.articles.length > 0 && (\n <CollectionPageSchema\n title={`Articles | ${config.siteName}`}\n description={`Browse all ${state.articles.length} articles on ${config.siteName}.`}\n url={`${config.siteUrl}/articles`}\n articleCount={state.articles.length}\n />\n )}\n </div>\n )\n}\n","import Image from 'next/image'\nimport Link from 'next/link'\nimport { Calendar, Clock, User } from 'lucide-react'\nimport type { Article } from './articleTypes'\n\ntype ArticleDetailHeroProps = Readonly<{\n article: Article\n categoryBasePath?: string\n showDate?: boolean\n showAuthor?: boolean\n}>\n\nfunction toSlug(cat: string): string {\n return cat\n .toLowerCase()\n .replaceAll(/\\s+/g, '-')\n .replaceAll(/[^a-z0-9-]/g, '')\n}\n\nexport function ArticleDetailHero({\n article,\n categoryBasePath = '/articles/category',\n showDate = false,\n showAuthor = true,\n}: ArticleDetailHeroProps) {\n return (\n <section\n style={{\n position: 'relative',\n height: '18rem',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n overflow: 'hidden',\n }}\n >\n <Image\n src={article.featuredImage}\n alt={article.title}\n fill\n sizes=\"100vw\"\n className=\"object-cover\"\n style={{ objectFit: 'cover' }}\n priority\n />\n <div\n style={{\n position: 'absolute',\n inset: 0,\n backgroundColor: 'rgba(0,0,0,0.6)',\n }}\n />\n <div\n style={{\n position: 'relative',\n zIndex: 10,\n textAlign: 'center',\n color: 'white',\n padding: '0 1rem',\n maxWidth: '56rem',\n margin: '0 auto',\n width: '100%',\n }}\n >\n {article.categories && article.categories.length > 0 && (\n <div\n style={{\n display: 'flex',\n flexWrap: 'wrap',\n justifyContent: 'center',\n gap: '0.5rem',\n marginBottom: '1rem',\n }}\n >\n {article.categories.slice(0, 4).map((cat) =>\n categoryBasePath ? (\n <Link\n key={cat}\n href={`${categoryBasePath}/${toSlug(cat)}`}\n className=\"inline-block bg-white/20 text-white text-sm font-medium px-3 py-1 rounded-full hover:bg-white/30 transition-colors\"\n >\n {cat}\n </Link>\n ) : (\n <span\n key={cat}\n className=\"inline-block bg-white/20 text-white text-sm font-medium px-3 py-1 rounded-full\"\n >\n {cat}\n </span>\n )\n )}\n </div>\n )}\n <h1 className=\"text-4xl md:text-5xl font-bold mb-4\">{article.title}</h1>\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '1.5rem',\n fontSize: '0.875rem',\n color: 'rgba(255,255,255,0.8)',\n }}\n >\n {showDate && article.date && (\n <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>\n <Calendar className=\"h-4 w-4\" />\n <span>{article.date}</span>\n </div>\n )}\n <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>\n <Clock className=\"h-4 w-4\" />\n <span>{article.readTime}</span>\n </div>\n {showAuthor && (\n <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>\n <User className=\"h-4 w-4\" />\n <span>By {article.author}</span>\n </div>\n )}\n </div>\n </div>\n </section>\n )\n}\n","'use client'\n\nimport Image from 'next/image'\nimport Link from 'next/link'\nimport { BreadcrumbSchema } from './ArticleSchemas'\nimport { LatestArticles } from './LatestArticles'\nimport { ArticlesConfig, DEFAULT_PAGE_SIZE } from './articlesConfig'\nimport type { Article } from './articleTypes'\n\nfunction getCategoryDescription(\n config: ArticlesConfig,\n slug: string,\n categoryName: string\n): { short: string; long?: string } {\n const raw = config.categoryDescriptions?.[slug]\n if (!raw) return { short: `Browse all articles in ${categoryName}.` }\n if (typeof raw === 'string') return { short: raw }\n return raw\n}\n\ntype CategoryArticlesPageProps = Readonly<{\n category: string\n articles: Article[]\n config: ArticlesConfig\n}>\n\nexport function CategoryArticlesPage({ category, articles, config }: CategoryArticlesPageProps) {\n if (articles.length === 0) return null\n\n const categoryName = articles[0].category\n const heroImage = articles[0].featuredImage\n const description = getCategoryDescription(config, category, categoryName)\n const pageSize = config.pageSize ?? DEFAULT_PAGE_SIZE\n const siteUrl = config.siteUrl.replace(/\\/$/, '')\n\n return (\n <div>\n <BreadcrumbSchema\n items={[\n { name: 'Home', url: siteUrl },\n { name: 'Articles', url: `${siteUrl}/articles` },\n { name: categoryName, url: `${siteUrl}/articles/category/${category}` },\n ]}\n />\n {/* Hero */}\n <section\n style={{\n position: 'relative',\n height: '20rem',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n overflow: 'hidden',\n }}\n >\n <Image\n src={heroImage}\n alt={categoryName}\n fill\n sizes=\"100vw\"\n style={{ objectFit: 'cover' }}\n priority\n />\n <div style={{ position: 'absolute', inset: 0, backgroundColor: 'rgba(0,0,0,0.6)' }} />\n <div\n style={{\n position: 'relative',\n zIndex: 10,\n textAlign: 'center',\n color: 'white',\n padding: '0 1rem',\n }}\n >\n <p className=\"text-sm font-semibold uppercase tracking-widest mb-3 opacity-80\">\n Category\n </p>\n <h1 className=\"text-4xl md:text-5xl font-bold mb-3\">{categoryName}</h1>\n {description.long && (\n <p className=\"text-lg opacity-90 max-w-2xl mx-auto mt-2\">{description.long}</p>\n )}\n <p className=\"text-lg opacity-70 mt-2\">\n {articles.length} article{articles.length === 1 ? '' : 's'}\n </p>\n </div>\n </section>\n\n {/* Articles */}\n <section className=\"py-16 bg-muted/50 flex-1\">\n <div className=\"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8\">\n <div className=\"mb-8 flex items-center justify-between\">\n <Link href=\"/articles\" className=\"text-sm text-primary hover:underline\">\n ← All Articles\n </Link>\n <p className=\"text-sm text-muted-foreground\">{description.short}</p>\n </div>\n <LatestArticles articles={articles} pageSize={pageSize} />\n </div>\n </section>\n </div>\n )\n}\n","'use client'\n\nimport { useState } from 'react'\nimport { Share2, Copy, Check, Mail, MessageCircle, Users, FileText } from 'lucide-react'\n\ninterface ArticleSocialShareProps {\n readonly title: string\n readonly url: string\n readonly excerpt?: string\n readonly shareMessage?: string\n}\n\nexport function ArticleSocialShare({ title, url, excerpt, shareMessage }: ArticleSocialShareProps) {\n const [copied, setCopied] = useState(false)\n\n const encodedTitle = encodeURIComponent(title)\n const encodedUrl = encodeURIComponent(url)\n const encodedExcerpt = encodeURIComponent(excerpt || '')\n\n const shareLinks = {\n linkedin: `https://www.linkedin.com/sharing/share-offsite/?url=${encodedUrl}`,\n facebook: `https://www.facebook.com/sharer/sharer.php?u=${encodedUrl}`,\n twitter: `https://twitter.com/intent/tweet?text=${encodedTitle}&url=${encodedUrl}`,\n reddit: `https://reddit.com/submit?url=${encodedUrl}&title=${encodedTitle}`,\n email: `mailto:?subject=${encodedTitle}&body=${encodedExcerpt}%0A%0A${encodedUrl}`,\n whatsapp: `https://wa.me/?text=${encodedTitle}%20${encodedUrl}`,\n telegram: `https://t.me/share/url?url=${encodedUrl}&text=${encodedTitle}`,\n }\n\n const copyToClipboard = async () => {\n try {\n await navigator.clipboard.writeText(url)\n setCopied(true)\n setTimeout(() => setCopied(false), 2000)\n } catch {\n // clipboard unavailable\n }\n }\n\n const openShareWindow = (shareUrl: string) => {\n globalThis.open(shareUrl, '_blank', 'width=600,height=400,scrollbars=yes,resizable=yes')\n }\n\n const btnClass =\n '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'\n\n return (\n <div className=\"border-t border-border pt-8 mt-8\">\n <div className=\"flex items-center gap-2 mb-4\">\n <Share2 className=\"h-5 w-5 text-muted-foreground\" />\n <h3 className=\"text-lg font-semibold text-foreground\">Share this article</h3>\n </div>\n\n <div className=\"flex flex-wrap gap-2\">\n <button className={btnClass} onClick={() => openShareWindow(shareLinks.linkedin)}>\n <Users className=\"h-4 w-4\" />\n LinkedIn\n </button>\n <button className={btnClass} onClick={() => openShareWindow(shareLinks.facebook)}>\n <span className=\"text-xs font-bold\">f</span> Facebook\n </button>\n <button className={btnClass} onClick={() => openShareWindow(shareLinks.twitter)}>\n <MessageCircle className=\"h-4 w-4\" />\n Twitter\n </button>\n <button className={btnClass} onClick={() => openShareWindow(shareLinks.reddit)}>\n <FileText className=\"h-4 w-4\" />\n Reddit\n </button>\n <button className={btnClass} onClick={() => openShareWindow(shareLinks.whatsapp)}>\n <MessageCircle className=\"h-4 w-4\" />\n WhatsApp\n </button>\n <button className={btnClass} onClick={() => openShareWindow(shareLinks.telegram)}>\n <MessageCircle className=\"h-4 w-4\" />\n Telegram\n </button>\n <a className={btnClass} href={shareLinks.email}>\n <Mail className=\"h-4 w-4\" />\n Email\n </a>\n <button className={btnClass} onClick={copyToClipboard}>\n {copied ? <Check className=\"h-4 w-4\" /> : <Copy className=\"h-4 w-4\" />}\n {copied ? 'Copied!' : 'Copy Link'}\n </button>\n </div>\n\n {shareMessage && <p className=\"text-sm text-muted-foreground mt-3\">{shareMessage}</p>}\n </div>\n )\n}\n","import Link from 'next/link'\nimport { ChevronLeft, ChevronRight } from 'lucide-react'\n\ninterface ArticleNavigationProps {\n readonly previous: { slug: string; title: string } | null\n readonly next: { slug: string; title: string } | null\n readonly basePath: string\n}\n\nfunction truncateTitle(title: string, maxLength = 60): string {\n return title.length > maxLength ? `${title.substring(0, maxLength)}...` : title\n}\n\nexport function ArticleNavigation({ previous, next, basePath }: ArticleNavigationProps) {\n if (!previous && !next) return null\n\n return (\n <nav className=\"mt-12 pt-8 border-t border-border\" aria-label=\"Article navigation\">\n <div className=\"flex justify-between gap-4\">\n <div className=\"flex-1 min-w-0\">\n {previous && (\n <Link\n href={`${basePath}/${previous.slug}`}\n className=\"group flex items-center gap-3 p-4 rounded-lg border border-border hover:border-primary/20 hover:bg-muted/50 transition-colors\"\n >\n <ChevronLeft className=\"h-5 w-5 text-muted-foreground group-hover:text-primary shrink-0\" />\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-sm text-muted-foreground mb-1\">Previous Article</div>\n <div className=\"font-medium text-foreground truncate\" title={previous.title}>\n {truncateTitle(previous.title)}\n </div>\n </div>\n </Link>\n )}\n </div>\n\n <div className=\"flex-1 min-w-0\">\n {next && (\n <Link\n href={`${basePath}/${next.slug}`}\n 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\"\n >\n <div className=\"min-w-0 flex-1 text-right\">\n <div className=\"text-sm text-muted-foreground mb-1\">Next Article</div>\n <div className=\"font-medium text-foreground truncate\" title={next.title}>\n {truncateTitle(next.title)}\n </div>\n </div>\n <ChevronRight className=\"h-5 w-5 text-muted-foreground group-hover:text-primary shrink-0\" />\n </Link>\n )}\n </div>\n </div>\n </nav>\n )\n}\n","import Link from 'next/link'\nimport { ArrowLeft } from 'lucide-react'\nimport type { ArticlesConfig } from './articlesConfig'\n\ntype ArticleBackLinkProps = Readonly<{\n config: Pick<ArticlesConfig, 'showBackToArticles'>\n href?: string\n label?: string\n className?: string\n}>\n\nexport function ArticleBackLink({\n config,\n href = '/articles',\n label = 'Back to Articles',\n className,\n}: ArticleBackLinkProps) {\n if (config.showBackToArticles === false) return null\n\n return (\n <Link\n href={href}\n className={\n className ??\n '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'\n }\n >\n <ArrowLeft className=\"h-4 w-4\" />\n {label}\n </Link>\n )\n}\n","import type { TocItem } from './articleTypes'\n\ntype ArticleTOCProps = Readonly<{ toc: TocItem[]; className?: string }>\n\nexport function ArticleTOC({ toc, className }: ArticleTOCProps) {\n if (!toc.length) return null\n return (\n <nav\n aria-label=\"Table of contents\"\n className={`mb-8 rounded-lg border border-border bg-muted/40 px-6 py-4 ${className ?? ''}`}\n >\n <p className=\"mb-3 text-sm font-semibold uppercase tracking-wide text-muted-foreground\">\n On this page\n </p>\n <ul className=\"space-y-1 text-sm\">\n {toc.map((item) => (\n <li key={item.id} style={{ paddingLeft: `${Math.max(0, item.depth - 2) * 1}rem` }}>\n <a\n href={`#${item.id}`}\n className=\"text-muted-foreground hover:text-foreground transition-colors\"\n >\n {item.text}\n </a>\n </li>\n ))}\n </ul>\n </nav>\n )\n}\n","'use client'\nimport { useEffect, useState } from 'react'\nimport { ArrowUp } from 'lucide-react'\n\nexport function ScrollToTop() {\n const [visible, setVisible] = useState(false)\n\n useEffect(() => {\n const onScroll = () => setVisible(globalThis.scrollY > 300)\n globalThis.addEventListener('scroll', onScroll, { passive: true })\n return () => globalThis.removeEventListener('scroll', onScroll)\n }, [])\n\n if (!visible) return null\n\n return (\n <button\n aria-label=\"Scroll to top\"\n onClick={() => globalThis.scrollTo({ top: 0, behavior: 'smooth' })}\n 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\"\n >\n <ArrowUp className=\"h-5 w-5\" />\n </button>\n )\n}\n","'use client'\n\nimport { useSession, signIn } from 'next-auth/react'\nimport { useCallback, useEffect, useState } from 'react'\nimport { CommentForm } from './CommentForm'\nimport { CommentThread } from './CommentThread'\nimport type { CommentsConfig } from './articlesConfig'\nimport type { ArticleCommentWithReplies } from './commentTypes'\n\ninterface CommentsSectionProps {\n readonly articleSlug: string\n readonly config: CommentsConfig\n}\n\nexport function CommentsSection({ articleSlug, config }: CommentsSectionProps) {\n const { data: session, status } = useSession()\n const [comments, setComments] = useState<ArticleCommentWithReplies[]>([])\n const [loading, setLoading] = useState(true)\n const [fetchError, setFetchError] = useState<string | null>(null)\n\n const perArticleEnabled = config.perArticleOverride?.[articleSlug] ?? true\n const enabled = config.enabled && perArticleEnabled\n\n const currentUserId = session?.user?.email ?? session?.user?.name ?? undefined\n\n const fetchComments = useCallback(async () => {\n setLoading(true)\n setFetchError(null)\n try {\n const res = await fetch(`/api/articles/${articleSlug}/comments`)\n if (!res.ok) throw new Error('Failed to load comments')\n const data = (await res.json()) as { comments: ArticleCommentWithReplies[] }\n setComments(data.comments)\n } catch {\n setFetchError('Could not load comments. Please try again.')\n } finally {\n setLoading(false)\n }\n }, [articleSlug])\n\n useEffect(() => {\n if (enabled) {\n fetchComments().catch(() => undefined)\n }\n }, [fetchComments, enabled])\n\n if (!enabled) return null\n\n const count = comments.length\n const label = count === 1 ? '1 comment' : `${count} comments`\n\n return (\n <section aria-label=\"Comments\" className=\"mt-12 pt-8 border-t border-border space-y-6\">\n <h2 className=\"text-xl font-semibold text-foreground\">{loading ? 'Comments' : label}</h2>\n\n {status === 'authenticated' ? (\n <CommentForm articleSlug={articleSlug} onSuccess={fetchComments} />\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n <button\n onClick={() => signIn()}\n className=\"text-primary underline hover:no-underline focus:outline-none\"\n >\n Sign in\n </button>{' '}\n to join the discussion.\n </p>\n )}\n\n {fetchError && <p className=\"text-sm text-destructive\">{fetchError}</p>}\n\n {loading ? (\n <p className=\"text-sm text-muted-foreground\">Loading comments…</p>\n ) : (\n <CommentThread\n comments={comments}\n articleSlug={articleSlug}\n currentUserId={currentUserId}\n onRefresh={fetchComments}\n />\n )}\n </section>\n )\n}\n","'use client'\n\nimport { useState } from 'react'\n\nconst MAX_LENGTH = 2000\nconst WARN_THRESHOLD = 1800\n\nfunction submitLabel(submitting: boolean, parentId?: string): string {\n if (submitting) return 'Posting…'\n return parentId ? 'Reply' : 'Post comment'\n}\n\ninterface CommentFormProps {\n readonly articleSlug: string\n readonly parentId?: string\n readonly onSuccess: () => void\n readonly onCancel?: () => void\n}\n\nexport function CommentForm({ articleSlug, parentId, onSuccess, onCancel }: CommentFormProps) {\n const [body, setBody] = useState('')\n const [submitting, setSubmitting] = useState(false)\n const [error, setError] = useState<string | null>(null)\n\n const remaining = MAX_LENGTH - body.length\n\n async function handleSubmit(e: React.FormEvent) {\n e.preventDefault()\n if (!body.trim() || submitting) return\n\n setSubmitting(true)\n setError(null)\n\n try {\n const res = await fetch(`/api/articles/${articleSlug}/comments`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ body: body.trim(), parentId: parentId ?? null }),\n })\n\n if (!res.ok) {\n const data = (await res.json()) as { error?: string }\n setError(data.error ?? 'Failed to post comment')\n return\n }\n\n setBody('')\n onSuccess()\n } catch {\n setError('Network error — please try again')\n } finally {\n setSubmitting(false)\n }\n }\n\n return (\n <form onSubmit={handleSubmit} className=\"space-y-2\">\n <textarea\n value={body}\n onChange={(e) => setBody(e.target.value)}\n maxLength={MAX_LENGTH}\n rows={parentId ? 3 : 4}\n placeholder={parentId ? 'Write a reply…' : 'Join the discussion…'}\n disabled={submitting}\n className=\"w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/50 disabled:opacity-50 resize-none\"\n aria-label={parentId ? 'Reply text' : 'Comment text'}\n />\n\n {remaining <= MAX_LENGTH - WARN_THRESHOLD && (\n <p className={`text-xs ${remaining < 0 ? 'text-destructive' : 'text-muted-foreground'}`}>\n {remaining} characters remaining\n </p>\n )}\n\n {error && <p className=\"text-xs text-destructive\">{error}</p>}\n\n <div className=\"flex gap-2\">\n <button\n type=\"submit\"\n disabled={submitting || body.trim().length === 0 || body.length > MAX_LENGTH}\n className=\"rounded-md bg-primary px-4 py-1.5 text-sm font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n {submitLabel(submitting, parentId)}\n </button>\n\n {onCancel && (\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"rounded-md px-4 py-1.5 text-sm font-medium text-muted-foreground hover:text-foreground\"\n >\n Cancel\n </button>\n )}\n </div>\n </form>\n )\n}\n","'use client'\n\nimport { useState } from 'react'\nimport { CommentForm } from './CommentForm'\nimport type { ArticleComment, ArticleCommentWithReplies } from './commentTypes'\n\nfunction relativeTime(iso: string): string {\n const diff = Date.now() - new Date(iso).getTime()\n const minutes = Math.floor(diff / 60_000)\n if (minutes < 1) return 'just now'\n if (minutes < 60) return `${minutes}m ago`\n const hours = Math.floor(minutes / 60)\n if (hours < 24) return `${hours}h ago`\n const days = Math.floor(hours / 24)\n if (days < 30) return `${days}d ago`\n const months = Math.floor(days / 30)\n if (months < 12) return `${months}mo ago`\n return `${Math.floor(months / 12)}y ago`\n}\n\ninterface CommentItemProps {\n readonly comment: ArticleCommentWithReplies | ArticleComment\n readonly articleSlug: string\n readonly currentUserId?: string\n readonly isReply?: boolean\n readonly onRefresh: () => void\n}\n\nexport function CommentItem({\n comment,\n articleSlug,\n currentUserId,\n isReply = false,\n onRefresh,\n}: CommentItemProps) {\n const [showReplyForm, setShowReplyForm] = useState(false)\n const [deleting, setDeleting] = useState(false)\n\n const replies = 'replies' in comment ? comment.replies : []\n const canReply = !isReply && !!currentUserId && !comment.isDeleted\n const canDelete = !!currentUserId && currentUserId === comment.authorId && !comment.isDeleted\n\n async function handleDelete() {\n if (deleting) return\n setDeleting(true)\n try {\n await fetch(`/api/articles/${articleSlug}/comments/${comment.id}`, { method: 'DELETE' })\n onRefresh()\n } finally {\n setDeleting(false)\n }\n }\n\n return (\n <div className={`${isReply ? 'ml-8 border-l-2 border-border pl-4' : ''}`}>\n <div className=\"rounded-lg bg-muted/40 p-3 space-y-1\">\n {comment.isDeleted ? (\n <p className=\"text-sm italic text-muted-foreground\">Comment removed</p>\n ) : (\n <>\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"text-sm font-medium text-foreground\">{comment.authorName}</span>\n <span className=\"text-xs text-muted-foreground\">\n {relativeTime(comment.createdAt)}\n </span>\n </div>\n <p className=\"text-sm text-foreground whitespace-pre-wrap break-words\">\n {comment.body}\n </p>\n <div className=\"flex gap-3 pt-1\">\n {canReply && (\n <button\n onClick={() => setShowReplyForm((v) => !v)}\n className=\"text-xs text-muted-foreground hover:text-foreground\"\n >\n {showReplyForm ? 'Cancel' : 'Reply'}\n </button>\n )}\n {canDelete && (\n <button\n onClick={handleDelete}\n disabled={deleting}\n className=\"text-xs text-muted-foreground hover:text-destructive disabled:opacity-50\"\n >\n {deleting ? 'Deleting…' : 'Delete'}\n </button>\n )}\n </div>\n </>\n )}\n </div>\n\n {showReplyForm && (\n <div className=\"mt-2 ml-2\">\n <CommentForm\n articleSlug={articleSlug}\n parentId={comment.id}\n onSuccess={() => {\n setShowReplyForm(false)\n onRefresh()\n }}\n onCancel={() => setShowReplyForm(false)}\n />\n </div>\n )}\n\n {replies.length > 0 && (\n <div className=\"mt-2 space-y-2\">\n {replies.map((reply) => (\n <CommentItem\n key={reply.id}\n comment={{ ...reply, replies: [] }}\n articleSlug={articleSlug}\n currentUserId={currentUserId}\n isReply\n onRefresh={onRefresh}\n />\n ))}\n </div>\n )}\n </div>\n )\n}\n","'use client'\n\nimport { CommentItem } from './CommentItem'\nimport type { ArticleCommentWithReplies } from './commentTypes'\n\ninterface CommentThreadProps {\n readonly comments: ArticleCommentWithReplies[]\n readonly articleSlug: string\n readonly currentUserId?: string\n readonly onRefresh: () => void\n}\n\nexport function CommentThread({\n comments,\n articleSlug,\n currentUserId,\n onRefresh,\n}: CommentThreadProps) {\n if (comments.length === 0) {\n return (\n <p className=\"text-sm text-muted-foreground text-center py-6\">\n No comments yet. Be the first to share your thoughts.\n </p>\n )\n }\n\n return (\n <div className=\"space-y-4\">\n {comments.map((comment) => (\n <CommentItem\n key={comment.id}\n comment={comment}\n articleSlug={articleSlug}\n currentUserId={currentUserId}\n onRefresh={onRefresh}\n />\n ))}\n </div>\n )\n}\n"],"mappings":"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","names":["jsx","jsxs","jsx","jsxs","Link","jsx","jsxs","Link","Image","jsx","jsxs","Search","useState","useEffect","Image","Link","ArrowRight","Calendar","Clock","jsx","jsxs","jsx","jsxs","useState","useEffect","jsx","jsxs","Search","useState","useEffect","useState","useEffect","jsx","jsxs","Image","Link","Calendar","Clock","User","jsx","jsxs","Image","Link","jsx","jsxs","Image","Link","useState","jsx","jsxs","useState","Link","jsx","jsxs","Link","jsx","jsxs","jsx","jsxs","useEffect","useState","jsx","useCallback","useEffect","useState","useState","jsx","jsxs","useState","e","useState","Fragment","jsx","jsxs","useState","jsx","jsx","jsxs","useState","useCallback","useEffect"]}