@fullstackdatasolutions/articles 0.2.1 → 0.4.2
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/README.md +99 -5
- package/dist/index.cjs +379 -106
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -1
- package/dist/index.d.ts +29 -1
- package/dist/index.js +371 -101
- package/dist/index.js.map +1 -1
- package/dist/server.cjs +2 -1
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +2 -1
- package/dist/server.js.map +1 -1
- package/package.json +8 -7
- package/src/ArticleCategoryGrid.tsx +1 -8
- package/src/ArticleDetailHero.tsx +122 -0
- package/src/ArticleNavigation.tsx +56 -0
- package/src/ArticleSocialShare.tsx +96 -0
- package/src/CategoryArticlesPage.tsx +21 -4
- package/src/__tests__/ArticleCategoryGrid.test.tsx +40 -1
- package/src/__tests__/ArticleDetailHero.test.tsx +134 -0
- package/src/__tests__/ArticleNavigation.test.tsx +127 -0
- package/src/__tests__/ArticleSocialShare.test.tsx +187 -0
- package/src/__tests__/ArticlesPage.test.tsx +147 -1
- package/src/__tests__/CommentItem.test.tsx +110 -0
- package/src/__tests__/seoUtils.test.ts +35 -0
- package/src/index.ts +4 -0
- package/src/seoUtils.ts +7 -1
package/dist/index.cjs
CHANGED
|
@@ -71,8 +71,11 @@ var src_exports = {};
|
|
|
71
71
|
__export(src_exports, {
|
|
72
72
|
ArticleCard: () => ArticleCard,
|
|
73
73
|
ArticleCategoryGrid: () => ArticleCategoryGrid,
|
|
74
|
+
ArticleDetailHero: () => ArticleDetailHero,
|
|
75
|
+
ArticleNavigation: () => ArticleNavigation,
|
|
74
76
|
ArticleSchema: () => ArticleSchema,
|
|
75
77
|
ArticleSearchBar: () => ArticleSearchBar,
|
|
78
|
+
ArticleSocialShare: () => ArticleSocialShare,
|
|
76
79
|
ArticlesHero: () => ArticlesHero,
|
|
77
80
|
ArticlesPage: () => ArticlesPage,
|
|
78
81
|
BreadcrumbSchema: () => BreadcrumbSchema,
|
|
@@ -110,37 +113,26 @@ function ArticleCategoryGrid({ categories, pageSize = 8 }) {
|
|
|
110
113
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "text-3xl font-bold text-foreground mb-4", children: "Browse by Category" }),
|
|
111
114
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-lg text-muted-foreground", children: "Explore our articles by topic to find the insights most relevant to your interests." })
|
|
112
115
|
] }),
|
|
113
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
114
|
-
"div",
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "p-4 text-center", children: [
|
|
134
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: "font-semibold text-foreground text-base", children: cat.name }),
|
|
135
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-sm text-muted-foreground mt-1", children: [
|
|
136
|
-
cat.count,
|
|
137
|
-
" ",
|
|
138
|
-
cat.count === 1 ? "article" : "articles"
|
|
139
|
-
] })
|
|
140
|
-
] })
|
|
141
|
-
] }) }, cat.slug))
|
|
142
|
-
}
|
|
143
|
-
),
|
|
116
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "grid md:grid-cols-2 lg:grid-cols-3 gap-6", children: visible.map((cat) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_link.default, { href: `/articles/category/${cat.slug}`, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "group overflow-hidden rounded-xl border border-border shadow-sm hover:shadow-lg transition-all duration-300 cursor-pointer bg-card", children: [
|
|
117
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "overflow-hidden", style: { position: "relative", height: "13rem" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
118
|
+
import_image.default,
|
|
119
|
+
{
|
|
120
|
+
src: cat.featuredImage,
|
|
121
|
+
alt: cat.name,
|
|
122
|
+
fill: true,
|
|
123
|
+
sizes: "(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw",
|
|
124
|
+
className: "object-cover group-hover:scale-105 transition-transform duration-300"
|
|
125
|
+
}
|
|
126
|
+
) }),
|
|
127
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "p-4 text-center", children: [
|
|
128
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: "font-semibold text-foreground text-base", children: cat.name }),
|
|
129
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-sm text-muted-foreground mt-1", children: [
|
|
130
|
+
cat.count,
|
|
131
|
+
" ",
|
|
132
|
+
cat.count === 1 ? "article" : "articles"
|
|
133
|
+
] })
|
|
134
|
+
] })
|
|
135
|
+
] }) }, cat.slug)) }),
|
|
144
136
|
hasMore && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mt-10 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
145
137
|
"button",
|
|
146
138
|
{
|
|
@@ -670,10 +662,140 @@ function ArticlesPage({ config }) {
|
|
|
670
662
|
] });
|
|
671
663
|
}
|
|
672
664
|
|
|
673
|
-
// src/
|
|
665
|
+
// src/ArticleDetailHero.tsx
|
|
674
666
|
var import_image4 = __toESM(require("next/image"), 1);
|
|
675
667
|
var import_link5 = __toESM(require("next/link"), 1);
|
|
668
|
+
var import_lucide_react5 = require("lucide-react");
|
|
676
669
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
670
|
+
function toSlug(cat) {
|
|
671
|
+
return cat.toLowerCase().replaceAll(/\s+/g, "-").replaceAll(/[^a-z0-9-]/g, "");
|
|
672
|
+
}
|
|
673
|
+
function ArticleDetailHero({
|
|
674
|
+
article,
|
|
675
|
+
categoryBasePath = "/articles/category",
|
|
676
|
+
showDate = false
|
|
677
|
+
}) {
|
|
678
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
679
|
+
"section",
|
|
680
|
+
{
|
|
681
|
+
style: {
|
|
682
|
+
position: "relative",
|
|
683
|
+
height: "18rem",
|
|
684
|
+
display: "flex",
|
|
685
|
+
alignItems: "center",
|
|
686
|
+
justifyContent: "center",
|
|
687
|
+
overflow: "hidden"
|
|
688
|
+
},
|
|
689
|
+
children: [
|
|
690
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
691
|
+
import_image4.default,
|
|
692
|
+
{
|
|
693
|
+
src: article.featuredImage,
|
|
694
|
+
alt: article.title,
|
|
695
|
+
fill: true,
|
|
696
|
+
sizes: "100vw",
|
|
697
|
+
className: "object-cover",
|
|
698
|
+
style: { objectFit: "cover" },
|
|
699
|
+
priority: true
|
|
700
|
+
}
|
|
701
|
+
),
|
|
702
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
703
|
+
"div",
|
|
704
|
+
{
|
|
705
|
+
style: {
|
|
706
|
+
position: "absolute",
|
|
707
|
+
inset: 0,
|
|
708
|
+
backgroundColor: "rgba(0,0,0,0.6)"
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
),
|
|
712
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
713
|
+
"div",
|
|
714
|
+
{
|
|
715
|
+
style: {
|
|
716
|
+
position: "relative",
|
|
717
|
+
zIndex: 10,
|
|
718
|
+
textAlign: "center",
|
|
719
|
+
color: "white",
|
|
720
|
+
padding: "0 1rem",
|
|
721
|
+
maxWidth: "56rem",
|
|
722
|
+
margin: "0 auto",
|
|
723
|
+
width: "100%"
|
|
724
|
+
},
|
|
725
|
+
children: [
|
|
726
|
+
article.categories && article.categories.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
727
|
+
"div",
|
|
728
|
+
{
|
|
729
|
+
style: {
|
|
730
|
+
display: "flex",
|
|
731
|
+
flexWrap: "wrap",
|
|
732
|
+
justifyContent: "center",
|
|
733
|
+
gap: "0.5rem",
|
|
734
|
+
marginBottom: "1rem"
|
|
735
|
+
},
|
|
736
|
+
children: article.categories.slice(0, 4).map(
|
|
737
|
+
(cat) => categoryBasePath ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
738
|
+
import_link5.default,
|
|
739
|
+
{
|
|
740
|
+
href: `${categoryBasePath}/${toSlug(cat)}`,
|
|
741
|
+
className: "inline-block bg-white/20 text-white text-sm font-medium px-3 py-1 rounded-full hover:bg-white/30 transition-colors",
|
|
742
|
+
children: cat
|
|
743
|
+
},
|
|
744
|
+
cat
|
|
745
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
746
|
+
"span",
|
|
747
|
+
{
|
|
748
|
+
className: "inline-block bg-white/20 text-white text-sm font-medium px-3 py-1 rounded-full",
|
|
749
|
+
children: cat
|
|
750
|
+
},
|
|
751
|
+
cat
|
|
752
|
+
)
|
|
753
|
+
)
|
|
754
|
+
}
|
|
755
|
+
),
|
|
756
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h1", { className: "text-4xl md:text-5xl font-bold mb-4", children: article.title }),
|
|
757
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
758
|
+
"div",
|
|
759
|
+
{
|
|
760
|
+
style: {
|
|
761
|
+
display: "flex",
|
|
762
|
+
alignItems: "center",
|
|
763
|
+
justifyContent: "center",
|
|
764
|
+
gap: "1.5rem",
|
|
765
|
+
fontSize: "0.875rem",
|
|
766
|
+
color: "rgba(255,255,255,0.8)"
|
|
767
|
+
},
|
|
768
|
+
children: [
|
|
769
|
+
showDate && article.date && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
|
|
770
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react5.Calendar, { className: "h-4 w-4" }),
|
|
771
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: article.date })
|
|
772
|
+
] }),
|
|
773
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
|
|
774
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react5.Clock, { className: "h-4 w-4" }),
|
|
775
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: article.readTime })
|
|
776
|
+
] }),
|
|
777
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
|
|
778
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react5.User, { className: "h-4 w-4" }),
|
|
779
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
|
|
780
|
+
"By ",
|
|
781
|
+
article.author
|
|
782
|
+
] })
|
|
783
|
+
] })
|
|
784
|
+
]
|
|
785
|
+
}
|
|
786
|
+
)
|
|
787
|
+
]
|
|
788
|
+
}
|
|
789
|
+
)
|
|
790
|
+
]
|
|
791
|
+
}
|
|
792
|
+
);
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
// src/CategoryArticlesPage.tsx
|
|
796
|
+
var import_image5 = __toESM(require("next/image"), 1);
|
|
797
|
+
var import_link6 = __toESM(require("next/link"), 1);
|
|
798
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
677
799
|
function getCategoryDescription(config, slug, categoryName) {
|
|
678
800
|
var _a;
|
|
679
801
|
const raw = (_a = config.categoryDescriptions) == null ? void 0 : _a[slug];
|
|
@@ -689,8 +811,8 @@ function CategoryArticlesPage({ category, articles, config }) {
|
|
|
689
811
|
const description = getCategoryDescription(config, category, categoryName);
|
|
690
812
|
const pageSize = (_a = config.pageSize) != null ? _a : DEFAULT_PAGE_SIZE;
|
|
691
813
|
const siteUrl = config.siteUrl.replace(/\/$/, "");
|
|
692
|
-
return /* @__PURE__ */ (0,
|
|
693
|
-
/* @__PURE__ */ (0,
|
|
814
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
|
|
815
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
694
816
|
BreadcrumbSchema,
|
|
695
817
|
{
|
|
696
818
|
items: [
|
|
@@ -700,47 +822,195 @@ function CategoryArticlesPage({ category, articles, config }) {
|
|
|
700
822
|
]
|
|
701
823
|
}
|
|
702
824
|
),
|
|
703
|
-
/* @__PURE__ */ (0,
|
|
704
|
-
|
|
705
|
-
|
|
825
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
826
|
+
"section",
|
|
827
|
+
{
|
|
828
|
+
style: {
|
|
829
|
+
position: "relative",
|
|
830
|
+
height: "20rem",
|
|
831
|
+
display: "flex",
|
|
832
|
+
alignItems: "center",
|
|
833
|
+
justifyContent: "center",
|
|
834
|
+
overflow: "hidden"
|
|
835
|
+
},
|
|
836
|
+
children: [
|
|
837
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
838
|
+
import_image5.default,
|
|
839
|
+
{
|
|
840
|
+
src: heroImage,
|
|
841
|
+
alt: categoryName,
|
|
842
|
+
fill: true,
|
|
843
|
+
sizes: "100vw",
|
|
844
|
+
style: { objectFit: "cover" },
|
|
845
|
+
priority: true
|
|
846
|
+
}
|
|
847
|
+
),
|
|
848
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: { position: "absolute", inset: 0, backgroundColor: "rgba(0,0,0,0.6)" } }),
|
|
849
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
850
|
+
"div",
|
|
851
|
+
{
|
|
852
|
+
style: {
|
|
853
|
+
position: "relative",
|
|
854
|
+
zIndex: 10,
|
|
855
|
+
textAlign: "center",
|
|
856
|
+
color: "white",
|
|
857
|
+
padding: "0 1rem"
|
|
858
|
+
},
|
|
859
|
+
children: [
|
|
860
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-sm font-semibold uppercase tracking-widest mb-3 opacity-80", children: "Category" }),
|
|
861
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h1", { className: "text-4xl md:text-5xl font-bold mb-3", children: categoryName }),
|
|
862
|
+
description.long && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-lg opacity-90 max-w-2xl mx-auto mt-2", children: description.long }),
|
|
863
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("p", { className: "text-lg opacity-70 mt-2", children: [
|
|
864
|
+
articles.length,
|
|
865
|
+
" article",
|
|
866
|
+
articles.length === 1 ? "" : "s"
|
|
867
|
+
] })
|
|
868
|
+
]
|
|
869
|
+
}
|
|
870
|
+
)
|
|
871
|
+
]
|
|
872
|
+
}
|
|
873
|
+
),
|
|
874
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("section", { className: "py-16 bg-muted/50 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: [
|
|
875
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "mb-8 flex items-center justify-between", children: [
|
|
876
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_link6.default, { href: "/articles", className: "text-sm text-primary hover:underline", children: "\u2190 All Articles" }),
|
|
877
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-sm text-muted-foreground", children: description.short })
|
|
878
|
+
] }),
|
|
879
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(LatestArticles, { articles, pageSize })
|
|
880
|
+
] }) })
|
|
881
|
+
] });
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
// src/ArticleSocialShare.tsx
|
|
885
|
+
var import_react4 = require("react");
|
|
886
|
+
var import_lucide_react6 = require("lucide-react");
|
|
887
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
888
|
+
function ArticleSocialShare({ title, url, excerpt, shareMessage }) {
|
|
889
|
+
const [copied, setCopied] = (0, import_react4.useState)(false);
|
|
890
|
+
const encodedTitle = encodeURIComponent(title);
|
|
891
|
+
const encodedUrl = encodeURIComponent(url);
|
|
892
|
+
const encodedExcerpt = encodeURIComponent(excerpt || "");
|
|
893
|
+
const shareLinks = {
|
|
894
|
+
linkedin: `https://www.linkedin.com/sharing/share-offsite/?url=${encodedUrl}`,
|
|
895
|
+
facebook: `https://www.facebook.com/sharer/sharer.php?u=${encodedUrl}`,
|
|
896
|
+
twitter: `https://twitter.com/intent/tweet?text=${encodedTitle}&url=${encodedUrl}`,
|
|
897
|
+
reddit: `https://reddit.com/submit?url=${encodedUrl}&title=${encodedTitle}`,
|
|
898
|
+
email: `mailto:?subject=${encodedTitle}&body=${encodedExcerpt}%0A%0A${encodedUrl}`,
|
|
899
|
+
whatsapp: `https://wa.me/?text=${encodedTitle}%20${encodedUrl}`,
|
|
900
|
+
telegram: `https://t.me/share/url?url=${encodedUrl}&text=${encodedTitle}`
|
|
901
|
+
};
|
|
902
|
+
const copyToClipboard = () => __async(this, null, function* () {
|
|
903
|
+
try {
|
|
904
|
+
yield navigator.clipboard.writeText(url);
|
|
905
|
+
setCopied(true);
|
|
906
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
907
|
+
} catch (e) {
|
|
908
|
+
}
|
|
909
|
+
});
|
|
910
|
+
const openShareWindow = (shareUrl) => {
|
|
911
|
+
window.open(shareUrl, "_blank", "width=600,height=400,scrollbars=yes,resizable=yes");
|
|
912
|
+
};
|
|
913
|
+
const btnClass = "inline-flex items-center gap-2 px-3 py-1.5 text-sm rounded-md border border-border bg-background text-foreground hover:bg-primary/10 hover:border-primary hover:text-primary transition-colors cursor-pointer";
|
|
914
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "border-t border-border pt-8 mt-8", children: [
|
|
915
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center gap-2 mb-4", children: [
|
|
916
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react6.Share2, { className: "h-5 w-5 text-muted-foreground" }),
|
|
917
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h3", { className: "text-lg font-semibold text-foreground", children: "Share this article" })
|
|
918
|
+
] }),
|
|
919
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex flex-wrap gap-2", children: [
|
|
920
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.linkedin), children: [
|
|
921
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react6.Users, { className: "h-4 w-4" }),
|
|
922
|
+
"LinkedIn"
|
|
923
|
+
] }),
|
|
924
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.facebook), children: [
|
|
925
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "text-xs font-bold", children: "f" }),
|
|
926
|
+
" Facebook"
|
|
927
|
+
] }),
|
|
928
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.twitter), children: [
|
|
929
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react6.MessageCircle, { className: "h-4 w-4" }),
|
|
930
|
+
"Twitter"
|
|
931
|
+
] }),
|
|
932
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.reddit), children: [
|
|
933
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react6.FileText, { className: "h-4 w-4" }),
|
|
934
|
+
"Reddit"
|
|
935
|
+
] }),
|
|
936
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.whatsapp), children: [
|
|
937
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react6.MessageCircle, { className: "h-4 w-4" }),
|
|
938
|
+
"WhatsApp"
|
|
939
|
+
] }),
|
|
940
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.telegram), children: [
|
|
941
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react6.MessageCircle, { className: "h-4 w-4" }),
|
|
942
|
+
"Telegram"
|
|
943
|
+
] }),
|
|
944
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
945
|
+
"button",
|
|
706
946
|
{
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
947
|
+
className: btnClass,
|
|
948
|
+
onClick: () => {
|
|
949
|
+
globalThis.location.href = shareLinks.email;
|
|
950
|
+
},
|
|
951
|
+
children: [
|
|
952
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react6.Mail, { className: "h-4 w-4" }),
|
|
953
|
+
"Email"
|
|
954
|
+
]
|
|
713
955
|
}
|
|
714
956
|
),
|
|
715
|
-
/* @__PURE__ */ (0,
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h1", { className: "text-4xl md:text-5xl font-bold mb-3", children: categoryName }),
|
|
719
|
-
description.long && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "text-lg opacity-90 max-w-2xl mx-auto mt-2", children: description.long }),
|
|
720
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("p", { className: "text-lg opacity-70 mt-2", children: [
|
|
721
|
-
articles.length,
|
|
722
|
-
" article",
|
|
723
|
-
articles.length === 1 ? "" : "s"
|
|
724
|
-
] })
|
|
957
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { className: btnClass, onClick: copyToClipboard, children: [
|
|
958
|
+
copied ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react6.Check, { className: "h-4 w-4" }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react6.Copy, { className: "h-4 w-4" }),
|
|
959
|
+
copied ? "Copied!" : "Copy Link"
|
|
725
960
|
] })
|
|
726
961
|
] }),
|
|
727
|
-
/* @__PURE__ */ (0,
|
|
728
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "mb-8 flex items-center justify-between", children: [
|
|
729
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_link5.default, { href: "/articles", className: "text-sm text-primary hover:underline", children: "\u2190 All Articles" }),
|
|
730
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "text-sm text-muted-foreground", children: description.short })
|
|
731
|
-
] }),
|
|
732
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(LatestArticles, { articles, pageSize })
|
|
733
|
-
] }) })
|
|
962
|
+
shareMessage && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-sm text-muted-foreground mt-3", children: shareMessage })
|
|
734
963
|
] });
|
|
735
964
|
}
|
|
736
965
|
|
|
966
|
+
// src/ArticleNavigation.tsx
|
|
967
|
+
var import_link7 = __toESM(require("next/link"), 1);
|
|
968
|
+
var import_lucide_react7 = require("lucide-react");
|
|
969
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
970
|
+
function truncateTitle(title, maxLength = 60) {
|
|
971
|
+
return title.length > maxLength ? `${title.substring(0, maxLength)}...` : title;
|
|
972
|
+
}
|
|
973
|
+
function ArticleNavigation({ previous, next, basePath }) {
|
|
974
|
+
if (!previous && !next) return null;
|
|
975
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("nav", { className: "mt-12 pt-8 border-t border-border", "aria-label": "Article navigation", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex justify-between gap-4", children: [
|
|
976
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "flex-1 min-w-0", children: previous && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
977
|
+
import_link7.default,
|
|
978
|
+
{
|
|
979
|
+
href: `${basePath}/${previous.slug}`,
|
|
980
|
+
className: "group flex items-center gap-3 p-4 rounded-lg border border-border hover:border-primary/20 hover:bg-muted/50 transition-colors",
|
|
981
|
+
children: [
|
|
982
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.ChevronLeft, { className: "h-5 w-5 text-muted-foreground group-hover:text-primary shrink-0" }),
|
|
983
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "min-w-0 flex-1", children: [
|
|
984
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "text-sm text-muted-foreground mb-1", children: "Previous Article" }),
|
|
985
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "font-medium text-foreground truncate", title: previous.title, children: truncateTitle(previous.title) })
|
|
986
|
+
] })
|
|
987
|
+
]
|
|
988
|
+
}
|
|
989
|
+
) }),
|
|
990
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "flex-1 min-w-0", children: next && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
991
|
+
import_link7.default,
|
|
992
|
+
{
|
|
993
|
+
href: `${basePath}/${next.slug}`,
|
|
994
|
+
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",
|
|
995
|
+
children: [
|
|
996
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "min-w-0 flex-1 text-right", children: [
|
|
997
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "text-sm text-muted-foreground mb-1", children: "Next Article" }),
|
|
998
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "font-medium text-foreground truncate", title: next.title, children: truncateTitle(next.title) })
|
|
999
|
+
] }),
|
|
1000
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.ChevronRight, { className: "h-5 w-5 text-muted-foreground group-hover:text-primary shrink-0" })
|
|
1001
|
+
]
|
|
1002
|
+
}
|
|
1003
|
+
) })
|
|
1004
|
+
] }) });
|
|
1005
|
+
}
|
|
1006
|
+
|
|
737
1007
|
// src/CommentsSection.tsx
|
|
738
|
-
var
|
|
739
|
-
var
|
|
1008
|
+
var import_react7 = require("next-auth/react");
|
|
1009
|
+
var import_react8 = require("react");
|
|
740
1010
|
|
|
741
1011
|
// src/CommentForm.tsx
|
|
742
|
-
var
|
|
743
|
-
var
|
|
1012
|
+
var import_react5 = require("react");
|
|
1013
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
744
1014
|
var MAX_LENGTH = 2e3;
|
|
745
1015
|
var WARN_THRESHOLD = 1800;
|
|
746
1016
|
function submitLabel(submitting, parentId) {
|
|
@@ -748,9 +1018,9 @@ function submitLabel(submitting, parentId) {
|
|
|
748
1018
|
return parentId ? "Reply" : "Post comment";
|
|
749
1019
|
}
|
|
750
1020
|
function CommentForm({ articleSlug, parentId, onSuccess, onCancel }) {
|
|
751
|
-
const [body, setBody] = (0,
|
|
752
|
-
const [submitting, setSubmitting] = (0,
|
|
753
|
-
const [error, setError] = (0,
|
|
1021
|
+
const [body, setBody] = (0, import_react5.useState)("");
|
|
1022
|
+
const [submitting, setSubmitting] = (0, import_react5.useState)(false);
|
|
1023
|
+
const [error, setError] = (0, import_react5.useState)(null);
|
|
754
1024
|
const remaining = MAX_LENGTH - body.length;
|
|
755
1025
|
function handleSubmit(e) {
|
|
756
1026
|
return __async(this, null, function* () {
|
|
@@ -779,8 +1049,8 @@ function CommentForm({ articleSlug, parentId, onSuccess, onCancel }) {
|
|
|
779
1049
|
}
|
|
780
1050
|
});
|
|
781
1051
|
}
|
|
782
|
-
return /* @__PURE__ */ (0,
|
|
783
|
-
/* @__PURE__ */ (0,
|
|
1052
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("form", { onSubmit: handleSubmit, className: "space-y-2", children: [
|
|
1053
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
784
1054
|
"textarea",
|
|
785
1055
|
{
|
|
786
1056
|
value: body,
|
|
@@ -793,13 +1063,13 @@ function CommentForm({ articleSlug, parentId, onSuccess, onCancel }) {
|
|
|
793
1063
|
"aria-label": parentId ? "Reply text" : "Comment text"
|
|
794
1064
|
}
|
|
795
1065
|
),
|
|
796
|
-
remaining <= MAX_LENGTH - WARN_THRESHOLD && /* @__PURE__ */ (0,
|
|
1066
|
+
remaining <= MAX_LENGTH - WARN_THRESHOLD && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("p", { className: `text-xs ${remaining < 0 ? "text-destructive" : "text-muted-foreground"}`, children: [
|
|
797
1067
|
remaining,
|
|
798
1068
|
" characters remaining"
|
|
799
1069
|
] }),
|
|
800
|
-
error && /* @__PURE__ */ (0,
|
|
801
|
-
/* @__PURE__ */ (0,
|
|
802
|
-
/* @__PURE__ */ (0,
|
|
1070
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-xs text-destructive", children: error }),
|
|
1071
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex gap-2", children: [
|
|
1072
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
803
1073
|
"button",
|
|
804
1074
|
{
|
|
805
1075
|
type: "submit",
|
|
@@ -808,7 +1078,7 @@ function CommentForm({ articleSlug, parentId, onSuccess, onCancel }) {
|
|
|
808
1078
|
children: submitLabel(submitting, parentId)
|
|
809
1079
|
}
|
|
810
1080
|
),
|
|
811
|
-
onCancel && /* @__PURE__ */ (0,
|
|
1081
|
+
onCancel && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
812
1082
|
"button",
|
|
813
1083
|
{
|
|
814
1084
|
type: "button",
|
|
@@ -822,8 +1092,8 @@ function CommentForm({ articleSlug, parentId, onSuccess, onCancel }) {
|
|
|
822
1092
|
}
|
|
823
1093
|
|
|
824
1094
|
// src/CommentItem.tsx
|
|
825
|
-
var
|
|
826
|
-
var
|
|
1095
|
+
var import_react6 = require("react");
|
|
1096
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
827
1097
|
function relativeTime(iso) {
|
|
828
1098
|
const diff = Date.now() - new Date(iso).getTime();
|
|
829
1099
|
const minutes = Math.floor(diff / 6e4);
|
|
@@ -844,8 +1114,8 @@ function CommentItem({
|
|
|
844
1114
|
isReply = false,
|
|
845
1115
|
onRefresh
|
|
846
1116
|
}) {
|
|
847
|
-
const [showReplyForm, setShowReplyForm] = (0,
|
|
848
|
-
const [deleting, setDeleting] = (0,
|
|
1117
|
+
const [showReplyForm, setShowReplyForm] = (0, import_react6.useState)(false);
|
|
1118
|
+
const [deleting, setDeleting] = (0, import_react6.useState)(false);
|
|
849
1119
|
const replies = "replies" in comment ? comment.replies : [];
|
|
850
1120
|
const canReply = !isReply && !!currentUserId && !comment.isDeleted;
|
|
851
1121
|
const canDelete = !!currentUserId && currentUserId === comment.authorId && !comment.isDeleted;
|
|
@@ -861,15 +1131,15 @@ function CommentItem({
|
|
|
861
1131
|
}
|
|
862
1132
|
});
|
|
863
1133
|
}
|
|
864
|
-
return /* @__PURE__ */ (0,
|
|
865
|
-
/* @__PURE__ */ (0,
|
|
866
|
-
/* @__PURE__ */ (0,
|
|
867
|
-
/* @__PURE__ */ (0,
|
|
868
|
-
/* @__PURE__ */ (0,
|
|
1134
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: `${isReply ? "ml-8 border-l-2 border-border pl-4" : ""}`, children: [
|
|
1135
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "rounded-lg bg-muted/40 p-3 space-y-1", children: comment.isDeleted ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-sm italic text-muted-foreground", children: "Comment removed" }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
1136
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
|
|
1137
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-sm font-medium text-foreground", children: comment.authorName }),
|
|
1138
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-xs text-muted-foreground", children: relativeTime(comment.createdAt) })
|
|
869
1139
|
] }),
|
|
870
|
-
/* @__PURE__ */ (0,
|
|
871
|
-
/* @__PURE__ */ (0,
|
|
872
|
-
canReply && /* @__PURE__ */ (0,
|
|
1140
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-sm text-foreground whitespace-pre-wrap break-words", children: comment.body }),
|
|
1141
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex gap-3 pt-1", children: [
|
|
1142
|
+
canReply && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
873
1143
|
"button",
|
|
874
1144
|
{
|
|
875
1145
|
onClick: () => setShowReplyForm((v) => !v),
|
|
@@ -877,7 +1147,7 @@ function CommentItem({
|
|
|
877
1147
|
children: showReplyForm ? "Cancel" : "Reply"
|
|
878
1148
|
}
|
|
879
1149
|
),
|
|
880
|
-
canDelete && /* @__PURE__ */ (0,
|
|
1150
|
+
canDelete && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
881
1151
|
"button",
|
|
882
1152
|
{
|
|
883
1153
|
onClick: handleDelete,
|
|
@@ -888,7 +1158,7 @@ function CommentItem({
|
|
|
888
1158
|
)
|
|
889
1159
|
] })
|
|
890
1160
|
] }) }),
|
|
891
|
-
showReplyForm && /* @__PURE__ */ (0,
|
|
1161
|
+
showReplyForm && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "mt-2 ml-2", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
892
1162
|
CommentForm,
|
|
893
1163
|
{
|
|
894
1164
|
articleSlug,
|
|
@@ -900,7 +1170,7 @@ function CommentItem({
|
|
|
900
1170
|
onCancel: () => setShowReplyForm(false)
|
|
901
1171
|
}
|
|
902
1172
|
) }),
|
|
903
|
-
replies.length > 0 && /* @__PURE__ */ (0,
|
|
1173
|
+
replies.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "mt-2 space-y-2", children: replies.map((reply) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
904
1174
|
CommentItem,
|
|
905
1175
|
{
|
|
906
1176
|
comment: __spreadProps(__spreadValues({}, reply), { replies: [] }),
|
|
@@ -915,7 +1185,7 @@ function CommentItem({
|
|
|
915
1185
|
}
|
|
916
1186
|
|
|
917
1187
|
// src/CommentThread.tsx
|
|
918
|
-
var
|
|
1188
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
919
1189
|
function CommentThread({
|
|
920
1190
|
comments,
|
|
921
1191
|
articleSlug,
|
|
@@ -923,9 +1193,9 @@ function CommentThread({
|
|
|
923
1193
|
onRefresh
|
|
924
1194
|
}) {
|
|
925
1195
|
if (comments.length === 0) {
|
|
926
|
-
return /* @__PURE__ */ (0,
|
|
1196
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-sm text-muted-foreground text-center py-6", children: "No comments yet. Be the first to share your thoughts." });
|
|
927
1197
|
}
|
|
928
|
-
return /* @__PURE__ */ (0,
|
|
1198
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "space-y-4", children: comments.map((comment) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
929
1199
|
CommentItem,
|
|
930
1200
|
{
|
|
931
1201
|
comment,
|
|
@@ -938,17 +1208,17 @@ function CommentThread({
|
|
|
938
1208
|
}
|
|
939
1209
|
|
|
940
1210
|
// src/CommentsSection.tsx
|
|
941
|
-
var
|
|
1211
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
942
1212
|
function CommentsSection({ articleSlug, config }) {
|
|
943
1213
|
var _a, _b, _c, _d, _e, _f;
|
|
944
|
-
const { data: session, status } = (0,
|
|
945
|
-
const [comments, setComments] = (0,
|
|
946
|
-
const [loading, setLoading] = (0,
|
|
947
|
-
const [fetchError, setFetchError] = (0,
|
|
1214
|
+
const { data: session, status } = (0, import_react7.useSession)();
|
|
1215
|
+
const [comments, setComments] = (0, import_react8.useState)([]);
|
|
1216
|
+
const [loading, setLoading] = (0, import_react8.useState)(true);
|
|
1217
|
+
const [fetchError, setFetchError] = (0, import_react8.useState)(null);
|
|
948
1218
|
const perArticleEnabled = (_b = (_a = config.perArticleOverride) == null ? void 0 : _a[articleSlug]) != null ? _b : true;
|
|
949
1219
|
const enabled = config.enabled && perArticleEnabled;
|
|
950
1220
|
const currentUserId = (_f = (_e = (_c = session == null ? void 0 : session.user) == null ? void 0 : _c.email) != null ? _e : (_d = session == null ? void 0 : session.user) == null ? void 0 : _d.name) != null ? _f : void 0;
|
|
951
|
-
const fetchComments = (0,
|
|
1221
|
+
const fetchComments = (0, import_react8.useCallback)(() => __async(this, null, function* () {
|
|
952
1222
|
setLoading(true);
|
|
953
1223
|
setFetchError(null);
|
|
954
1224
|
try {
|
|
@@ -962,7 +1232,7 @@ function CommentsSection({ articleSlug, config }) {
|
|
|
962
1232
|
setLoading(false);
|
|
963
1233
|
}
|
|
964
1234
|
}), [articleSlug]);
|
|
965
|
-
(0,
|
|
1235
|
+
(0, import_react8.useEffect)(() => {
|
|
966
1236
|
if (enabled) {
|
|
967
1237
|
fetchComments().catch(() => void 0);
|
|
968
1238
|
}
|
|
@@ -970,13 +1240,13 @@ function CommentsSection({ articleSlug, config }) {
|
|
|
970
1240
|
if (!enabled) return null;
|
|
971
1241
|
const count = comments.length;
|
|
972
1242
|
const label = count === 1 ? "1 comment" : `${count} comments`;
|
|
973
|
-
return /* @__PURE__ */ (0,
|
|
974
|
-
/* @__PURE__ */ (0,
|
|
975
|
-
status === "authenticated" ? /* @__PURE__ */ (0,
|
|
976
|
-
/* @__PURE__ */ (0,
|
|
1243
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("section", { "aria-label": "Comments", className: "mt-12 pt-8 border-t border-border space-y-6", children: [
|
|
1244
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h2", { className: "text-xl font-semibold text-foreground", children: loading ? "Comments" : label }),
|
|
1245
|
+
status === "authenticated" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(CommentForm, { articleSlug, onSuccess: fetchComments }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("p", { className: "text-sm text-muted-foreground", children: [
|
|
1246
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
977
1247
|
"button",
|
|
978
1248
|
{
|
|
979
|
-
onClick: () => (0,
|
|
1249
|
+
onClick: () => (0, import_react7.signIn)(),
|
|
980
1250
|
className: "text-primary underline hover:no-underline focus:outline-none",
|
|
981
1251
|
children: "Sign in"
|
|
982
1252
|
}
|
|
@@ -984,8 +1254,8 @@ function CommentsSection({ articleSlug, config }) {
|
|
|
984
1254
|
" ",
|
|
985
1255
|
"to join the discussion."
|
|
986
1256
|
] }),
|
|
987
|
-
fetchError && /* @__PURE__ */ (0,
|
|
988
|
-
loading ? /* @__PURE__ */ (0,
|
|
1257
|
+
fetchError && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-sm text-destructive", children: fetchError }),
|
|
1258
|
+
loading ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-sm text-muted-foreground", children: "Loading comments\u2026" }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
989
1259
|
CommentThread,
|
|
990
1260
|
{
|
|
991
1261
|
comments,
|
|
@@ -1000,8 +1270,11 @@ function CommentsSection({ articleSlug, config }) {
|
|
|
1000
1270
|
0 && (module.exports = {
|
|
1001
1271
|
ArticleCard,
|
|
1002
1272
|
ArticleCategoryGrid,
|
|
1273
|
+
ArticleDetailHero,
|
|
1274
|
+
ArticleNavigation,
|
|
1003
1275
|
ArticleSchema,
|
|
1004
1276
|
ArticleSearchBar,
|
|
1277
|
+
ArticleSocialShare,
|
|
1005
1278
|
ArticlesHero,
|
|
1006
1279
|
ArticlesPage,
|
|
1007
1280
|
BreadcrumbSchema,
|