@fullstackdatasolutions/articles 0.3.0 → 0.4.3

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
@@ -615,7 +615,11 @@ import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
615
615
  function toSlug(cat) {
616
616
  return cat.toLowerCase().replaceAll(/\s+/g, "-").replaceAll(/[^a-z0-9-]/g, "");
617
617
  }
618
- function ArticleDetailHero({ article, categoryBasePath }) {
618
+ function ArticleDetailHero({
619
+ article,
620
+ categoryBasePath = "/articles/category",
621
+ showDate = false
622
+ }) {
619
623
  return /* @__PURE__ */ jsxs9(
620
624
  "section",
621
625
  {
@@ -636,6 +640,7 @@ function ArticleDetailHero({ article, categoryBasePath }) {
636
640
  fill: true,
637
641
  sizes: "100vw",
638
642
  className: "object-cover",
643
+ style: { objectFit: "cover" },
639
644
  priority: true
640
645
  }
641
646
  ),
@@ -663,42 +668,67 @@ function ArticleDetailHero({ article, categoryBasePath }) {
663
668
  width: "100%"
664
669
  },
665
670
  children: [
666
- article.categories && article.categories.length > 0 && /* @__PURE__ */ jsx10("div", { style: { display: "flex", flexWrap: "wrap", justifyContent: "center", gap: "0.5rem", marginBottom: "1rem" }, children: article.categories.slice(0, 4).map(
667
- (cat) => categoryBasePath ? /* @__PURE__ */ jsx10(
668
- Link5,
669
- {
670
- href: `${categoryBasePath}/${toSlug(cat)}`,
671
- className: "inline-block bg-white/20 text-white text-sm font-medium px-3 py-1 rounded-full hover:bg-white/30 transition-colors",
672
- children: cat
673
- },
674
- cat
675
- ) : /* @__PURE__ */ jsx10(
676
- "span",
677
- {
678
- className: "inline-block bg-white/20 text-white text-sm font-medium px-3 py-1 rounded-full",
679
- children: cat
671
+ article.categories && article.categories.length > 0 && /* @__PURE__ */ jsx10(
672
+ "div",
673
+ {
674
+ style: {
675
+ display: "flex",
676
+ flexWrap: "wrap",
677
+ justifyContent: "center",
678
+ gap: "0.5rem",
679
+ marginBottom: "1rem"
680
680
  },
681
- cat
682
- )
683
- ) }),
681
+ children: article.categories.slice(0, 4).map(
682
+ (cat) => categoryBasePath ? /* @__PURE__ */ jsx10(
683
+ Link5,
684
+ {
685
+ href: `${categoryBasePath}/${toSlug(cat)}`,
686
+ className: "inline-block bg-white/20 text-white text-sm font-medium px-3 py-1 rounded-full hover:bg-white/30 transition-colors",
687
+ children: cat
688
+ },
689
+ cat
690
+ ) : /* @__PURE__ */ jsx10(
691
+ "span",
692
+ {
693
+ className: "inline-block bg-white/20 text-white text-sm font-medium px-3 py-1 rounded-full",
694
+ children: cat
695
+ },
696
+ cat
697
+ )
698
+ )
699
+ }
700
+ ),
684
701
  /* @__PURE__ */ jsx10("h1", { className: "text-4xl md:text-5xl font-bold mb-4", children: article.title }),
685
- /* @__PURE__ */ jsxs9("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: "1.5rem", fontSize: "0.875rem", color: "rgba(255,255,255,0.8)" }, children: [
686
- article.date && /* @__PURE__ */ jsxs9("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
687
- /* @__PURE__ */ jsx10(Calendar3, { className: "h-4 w-4" }),
688
- /* @__PURE__ */ jsx10("span", { children: article.date })
689
- ] }),
690
- /* @__PURE__ */ jsxs9("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
691
- /* @__PURE__ */ jsx10(Clock3, { className: "h-4 w-4" }),
692
- /* @__PURE__ */ jsx10("span", { children: article.readTime })
693
- ] }),
694
- /* @__PURE__ */ jsxs9("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
695
- /* @__PURE__ */ jsx10(User2, { className: "h-4 w-4" }),
696
- /* @__PURE__ */ jsxs9("span", { children: [
697
- "By ",
698
- article.author
699
- ] })
700
- ] })
701
- ] })
702
+ /* @__PURE__ */ jsxs9(
703
+ "div",
704
+ {
705
+ style: {
706
+ display: "flex",
707
+ alignItems: "center",
708
+ justifyContent: "center",
709
+ gap: "1.5rem",
710
+ fontSize: "0.875rem",
711
+ color: "rgba(255,255,255,0.8)"
712
+ },
713
+ children: [
714
+ showDate && article.date && /* @__PURE__ */ jsxs9("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
715
+ /* @__PURE__ */ jsx10(Calendar3, { className: "h-4 w-4" }),
716
+ /* @__PURE__ */ jsx10("span", { children: article.date })
717
+ ] }),
718
+ /* @__PURE__ */ jsxs9("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
719
+ /* @__PURE__ */ jsx10(Clock3, { className: "h-4 w-4" }),
720
+ /* @__PURE__ */ jsx10("span", { children: article.readTime })
721
+ ] }),
722
+ /* @__PURE__ */ jsxs9("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
723
+ /* @__PURE__ */ jsx10(User2, { className: "h-4 w-4" }),
724
+ /* @__PURE__ */ jsxs9("span", { children: [
725
+ "By ",
726
+ article.author
727
+ ] })
728
+ ] })
729
+ ]
730
+ }
731
+ )
702
732
  ]
703
733
  }
704
734
  )
@@ -737,30 +767,55 @@ function CategoryArticlesPage({ category, articles, config }) {
737
767
  ]
738
768
  }
739
769
  ),
740
- /* @__PURE__ */ jsxs10("section", { className: "relative h-72 md:h-96 flex items-center justify-center overflow-hidden", children: [
741
- /* @__PURE__ */ jsx11(
742
- Image5,
743
- {
744
- src: heroImage,
745
- alt: categoryName,
746
- fill: true,
747
- sizes: "100vw",
748
- className: "object-cover",
749
- priority: true
750
- }
751
- ),
752
- /* @__PURE__ */ jsx11("div", { className: "absolute inset-0 bg-black/60" }),
753
- /* @__PURE__ */ jsxs10("div", { className: "relative z-10 text-center text-white px-4", children: [
754
- /* @__PURE__ */ jsx11("p", { className: "text-sm font-semibold uppercase tracking-widest mb-3 opacity-80", children: "Category" }),
755
- /* @__PURE__ */ jsx11("h1", { className: "text-4xl md:text-5xl font-bold mb-3", children: categoryName }),
756
- description.long && /* @__PURE__ */ jsx11("p", { className: "text-lg opacity-90 max-w-2xl mx-auto mt-2", children: description.long }),
757
- /* @__PURE__ */ jsxs10("p", { className: "text-lg opacity-70 mt-2", children: [
758
- articles.length,
759
- " article",
760
- articles.length === 1 ? "" : "s"
761
- ] })
762
- ] })
763
- ] }),
770
+ /* @__PURE__ */ jsxs10(
771
+ "section",
772
+ {
773
+ style: {
774
+ position: "relative",
775
+ height: "20rem",
776
+ display: "flex",
777
+ alignItems: "center",
778
+ justifyContent: "center",
779
+ overflow: "hidden"
780
+ },
781
+ children: [
782
+ /* @__PURE__ */ jsx11(
783
+ Image5,
784
+ {
785
+ src: heroImage,
786
+ alt: categoryName,
787
+ fill: true,
788
+ sizes: "100vw",
789
+ style: { objectFit: "cover" },
790
+ priority: true
791
+ }
792
+ ),
793
+ /* @__PURE__ */ jsx11("div", { style: { position: "absolute", inset: 0, backgroundColor: "rgba(0,0,0,0.6)" } }),
794
+ /* @__PURE__ */ jsxs10(
795
+ "div",
796
+ {
797
+ style: {
798
+ position: "relative",
799
+ zIndex: 10,
800
+ textAlign: "center",
801
+ color: "white",
802
+ padding: "0 1rem"
803
+ },
804
+ children: [
805
+ /* @__PURE__ */ jsx11("p", { className: "text-sm font-semibold uppercase tracking-widest mb-3 opacity-80", children: "Category" }),
806
+ /* @__PURE__ */ jsx11("h1", { className: "text-4xl md:text-5xl font-bold mb-3", children: categoryName }),
807
+ description.long && /* @__PURE__ */ jsx11("p", { className: "text-lg opacity-90 max-w-2xl mx-auto mt-2", children: description.long }),
808
+ /* @__PURE__ */ jsxs10("p", { className: "text-lg opacity-70 mt-2", children: [
809
+ articles.length,
810
+ " article",
811
+ articles.length === 1 ? "" : "s"
812
+ ] })
813
+ ]
814
+ }
815
+ )
816
+ ]
817
+ }
818
+ ),
764
819
  /* @__PURE__ */ jsx11("section", { className: "py-16 bg-muted/50 flex-1", children: /* @__PURE__ */ jsxs10("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: [
765
820
  /* @__PURE__ */ jsxs10("div", { className: "mb-8 flex items-center justify-between", children: [
766
821
  /* @__PURE__ */ jsx11(Link6, { href: "/articles", className: "text-sm text-primary hover:underline", children: "\u2190 All Articles" }),
@@ -771,13 +826,136 @@ function CategoryArticlesPage({ category, articles, config }) {
771
826
  ] });
772
827
  }
773
828
 
829
+ // src/ArticleSocialShare.tsx
830
+ import { useState as useState4 } from "react";
831
+ import { Share2, Copy, Check, Mail, MessageCircle, Users, FileText } from "lucide-react";
832
+ import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
833
+ function ArticleSocialShare({ title, url, excerpt, shareMessage }) {
834
+ const [copied, setCopied] = useState4(false);
835
+ const encodedTitle = encodeURIComponent(title);
836
+ const encodedUrl = encodeURIComponent(url);
837
+ const encodedExcerpt = encodeURIComponent(excerpt || "");
838
+ const shareLinks = {
839
+ linkedin: `https://www.linkedin.com/sharing/share-offsite/?url=${encodedUrl}`,
840
+ facebook: `https://www.facebook.com/sharer/sharer.php?u=${encodedUrl}`,
841
+ twitter: `https://twitter.com/intent/tweet?text=${encodedTitle}&url=${encodedUrl}`,
842
+ reddit: `https://reddit.com/submit?url=${encodedUrl}&title=${encodedTitle}`,
843
+ email: `mailto:?subject=${encodedTitle}&body=${encodedExcerpt}%0A%0A${encodedUrl}`,
844
+ whatsapp: `https://wa.me/?text=${encodedTitle}%20${encodedUrl}`,
845
+ telegram: `https://t.me/share/url?url=${encodedUrl}&text=${encodedTitle}`
846
+ };
847
+ const copyToClipboard = () => __async(this, null, function* () {
848
+ try {
849
+ yield navigator.clipboard.writeText(url);
850
+ setCopied(true);
851
+ setTimeout(() => setCopied(false), 2e3);
852
+ } catch (e) {
853
+ }
854
+ });
855
+ const openShareWindow = (shareUrl) => {
856
+ window.open(shareUrl, "_blank", "width=600,height=400,scrollbars=yes,resizable=yes");
857
+ };
858
+ 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";
859
+ return /* @__PURE__ */ jsxs11("div", { className: "border-t border-border pt-8 mt-8", children: [
860
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2 mb-4", children: [
861
+ /* @__PURE__ */ jsx12(Share2, { className: "h-5 w-5 text-muted-foreground" }),
862
+ /* @__PURE__ */ jsx12("h3", { className: "text-lg font-semibold text-foreground", children: "Share this article" })
863
+ ] }),
864
+ /* @__PURE__ */ jsxs11("div", { className: "flex flex-wrap gap-2", children: [
865
+ /* @__PURE__ */ jsxs11("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.linkedin), children: [
866
+ /* @__PURE__ */ jsx12(Users, { className: "h-4 w-4" }),
867
+ "LinkedIn"
868
+ ] }),
869
+ /* @__PURE__ */ jsxs11("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.facebook), children: [
870
+ /* @__PURE__ */ jsx12("span", { className: "text-xs font-bold", children: "f" }),
871
+ " Facebook"
872
+ ] }),
873
+ /* @__PURE__ */ jsxs11("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.twitter), children: [
874
+ /* @__PURE__ */ jsx12(MessageCircle, { className: "h-4 w-4" }),
875
+ "Twitter"
876
+ ] }),
877
+ /* @__PURE__ */ jsxs11("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.reddit), children: [
878
+ /* @__PURE__ */ jsx12(FileText, { className: "h-4 w-4" }),
879
+ "Reddit"
880
+ ] }),
881
+ /* @__PURE__ */ jsxs11("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.whatsapp), children: [
882
+ /* @__PURE__ */ jsx12(MessageCircle, { className: "h-4 w-4" }),
883
+ "WhatsApp"
884
+ ] }),
885
+ /* @__PURE__ */ jsxs11("button", { className: btnClass, onClick: () => openShareWindow(shareLinks.telegram), children: [
886
+ /* @__PURE__ */ jsx12(MessageCircle, { className: "h-4 w-4" }),
887
+ "Telegram"
888
+ ] }),
889
+ /* @__PURE__ */ jsxs11(
890
+ "button",
891
+ {
892
+ className: btnClass,
893
+ onClick: () => {
894
+ globalThis.location.href = shareLinks.email;
895
+ },
896
+ children: [
897
+ /* @__PURE__ */ jsx12(Mail, { className: "h-4 w-4" }),
898
+ "Email"
899
+ ]
900
+ }
901
+ ),
902
+ /* @__PURE__ */ jsxs11("button", { className: btnClass, onClick: copyToClipboard, children: [
903
+ copied ? /* @__PURE__ */ jsx12(Check, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx12(Copy, { className: "h-4 w-4" }),
904
+ copied ? "Copied!" : "Copy Link"
905
+ ] })
906
+ ] }),
907
+ shareMessage && /* @__PURE__ */ jsx12("p", { className: "text-sm text-muted-foreground mt-3", children: shareMessage })
908
+ ] });
909
+ }
910
+
911
+ // src/ArticleNavigation.tsx
912
+ import Link7 from "next/link";
913
+ import { ChevronLeft, ChevronRight } from "lucide-react";
914
+ import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
915
+ function truncateTitle(title, maxLength = 60) {
916
+ return title.length > maxLength ? `${title.substring(0, maxLength)}...` : title;
917
+ }
918
+ function ArticleNavigation({ previous, next, basePath }) {
919
+ if (!previous && !next) return null;
920
+ return /* @__PURE__ */ jsx13("nav", { className: "mt-12 pt-8 border-t border-border", "aria-label": "Article navigation", children: /* @__PURE__ */ jsxs12("div", { className: "flex justify-between gap-4", children: [
921
+ /* @__PURE__ */ jsx13("div", { className: "flex-1 min-w-0", children: previous && /* @__PURE__ */ jsxs12(
922
+ Link7,
923
+ {
924
+ href: `${basePath}/${previous.slug}`,
925
+ className: "group flex items-center gap-3 p-4 rounded-lg border border-border hover:border-primary/20 hover:bg-muted/50 transition-colors",
926
+ children: [
927
+ /* @__PURE__ */ jsx13(ChevronLeft, { className: "h-5 w-5 text-muted-foreground group-hover:text-primary shrink-0" }),
928
+ /* @__PURE__ */ jsxs12("div", { className: "min-w-0 flex-1", children: [
929
+ /* @__PURE__ */ jsx13("div", { className: "text-sm text-muted-foreground mb-1", children: "Previous Article" }),
930
+ /* @__PURE__ */ jsx13("div", { className: "font-medium text-foreground truncate", title: previous.title, children: truncateTitle(previous.title) })
931
+ ] })
932
+ ]
933
+ }
934
+ ) }),
935
+ /* @__PURE__ */ jsx13("div", { className: "flex-1 min-w-0", children: next && /* @__PURE__ */ jsxs12(
936
+ Link7,
937
+ {
938
+ href: `${basePath}/${next.slug}`,
939
+ 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",
940
+ children: [
941
+ /* @__PURE__ */ jsxs12("div", { className: "min-w-0 flex-1 text-right", children: [
942
+ /* @__PURE__ */ jsx13("div", { className: "text-sm text-muted-foreground mb-1", children: "Next Article" }),
943
+ /* @__PURE__ */ jsx13("div", { className: "font-medium text-foreground truncate", title: next.title, children: truncateTitle(next.title) })
944
+ ] }),
945
+ /* @__PURE__ */ jsx13(ChevronRight, { className: "h-5 w-5 text-muted-foreground group-hover:text-primary shrink-0" })
946
+ ]
947
+ }
948
+ ) })
949
+ ] }) });
950
+ }
951
+
774
952
  // src/CommentsSection.tsx
775
953
  import { useSession, signIn } from "next-auth/react";
776
- import { useCallback as useCallback2, useEffect as useEffect4, useState as useState6 } from "react";
954
+ import { useCallback as useCallback2, useEffect as useEffect4, useState as useState7 } from "react";
777
955
 
778
956
  // src/CommentForm.tsx
779
- import { useState as useState4 } from "react";
780
- import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
957
+ import { useState as useState5 } from "react";
958
+ import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
781
959
  var MAX_LENGTH = 2e3;
782
960
  var WARN_THRESHOLD = 1800;
783
961
  function submitLabel(submitting, parentId) {
@@ -785,9 +963,9 @@ function submitLabel(submitting, parentId) {
785
963
  return parentId ? "Reply" : "Post comment";
786
964
  }
787
965
  function CommentForm({ articleSlug, parentId, onSuccess, onCancel }) {
788
- const [body, setBody] = useState4("");
789
- const [submitting, setSubmitting] = useState4(false);
790
- const [error, setError] = useState4(null);
966
+ const [body, setBody] = useState5("");
967
+ const [submitting, setSubmitting] = useState5(false);
968
+ const [error, setError] = useState5(null);
791
969
  const remaining = MAX_LENGTH - body.length;
792
970
  function handleSubmit(e) {
793
971
  return __async(this, null, function* () {
@@ -816,8 +994,8 @@ function CommentForm({ articleSlug, parentId, onSuccess, onCancel }) {
816
994
  }
817
995
  });
818
996
  }
819
- return /* @__PURE__ */ jsxs11("form", { onSubmit: handleSubmit, className: "space-y-2", children: [
820
- /* @__PURE__ */ jsx12(
997
+ return /* @__PURE__ */ jsxs13("form", { onSubmit: handleSubmit, className: "space-y-2", children: [
998
+ /* @__PURE__ */ jsx14(
821
999
  "textarea",
822
1000
  {
823
1001
  value: body,
@@ -830,13 +1008,13 @@ function CommentForm({ articleSlug, parentId, onSuccess, onCancel }) {
830
1008
  "aria-label": parentId ? "Reply text" : "Comment text"
831
1009
  }
832
1010
  ),
833
- remaining <= MAX_LENGTH - WARN_THRESHOLD && /* @__PURE__ */ jsxs11("p", { className: `text-xs ${remaining < 0 ? "text-destructive" : "text-muted-foreground"}`, children: [
1011
+ remaining <= MAX_LENGTH - WARN_THRESHOLD && /* @__PURE__ */ jsxs13("p", { className: `text-xs ${remaining < 0 ? "text-destructive" : "text-muted-foreground"}`, children: [
834
1012
  remaining,
835
1013
  " characters remaining"
836
1014
  ] }),
837
- error && /* @__PURE__ */ jsx12("p", { className: "text-xs text-destructive", children: error }),
838
- /* @__PURE__ */ jsxs11("div", { className: "flex gap-2", children: [
839
- /* @__PURE__ */ jsx12(
1015
+ error && /* @__PURE__ */ jsx14("p", { className: "text-xs text-destructive", children: error }),
1016
+ /* @__PURE__ */ jsxs13("div", { className: "flex gap-2", children: [
1017
+ /* @__PURE__ */ jsx14(
840
1018
  "button",
841
1019
  {
842
1020
  type: "submit",
@@ -845,7 +1023,7 @@ function CommentForm({ articleSlug, parentId, onSuccess, onCancel }) {
845
1023
  children: submitLabel(submitting, parentId)
846
1024
  }
847
1025
  ),
848
- onCancel && /* @__PURE__ */ jsx12(
1026
+ onCancel && /* @__PURE__ */ jsx14(
849
1027
  "button",
850
1028
  {
851
1029
  type: "button",
@@ -859,8 +1037,8 @@ function CommentForm({ articleSlug, parentId, onSuccess, onCancel }) {
859
1037
  }
860
1038
 
861
1039
  // src/CommentItem.tsx
862
- import { useState as useState5 } from "react";
863
- import { Fragment, jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
1040
+ import { useState as useState6 } from "react";
1041
+ import { Fragment, jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
864
1042
  function relativeTime(iso) {
865
1043
  const diff = Date.now() - new Date(iso).getTime();
866
1044
  const minutes = Math.floor(diff / 6e4);
@@ -881,8 +1059,8 @@ function CommentItem({
881
1059
  isReply = false,
882
1060
  onRefresh
883
1061
  }) {
884
- const [showReplyForm, setShowReplyForm] = useState5(false);
885
- const [deleting, setDeleting] = useState5(false);
1062
+ const [showReplyForm, setShowReplyForm] = useState6(false);
1063
+ const [deleting, setDeleting] = useState6(false);
886
1064
  const replies = "replies" in comment ? comment.replies : [];
887
1065
  const canReply = !isReply && !!currentUserId && !comment.isDeleted;
888
1066
  const canDelete = !!currentUserId && currentUserId === comment.authorId && !comment.isDeleted;
@@ -898,15 +1076,15 @@ function CommentItem({
898
1076
  }
899
1077
  });
900
1078
  }
901
- return /* @__PURE__ */ jsxs12("div", { className: `${isReply ? "ml-8 border-l-2 border-border pl-4" : ""}`, children: [
902
- /* @__PURE__ */ jsx13("div", { className: "rounded-lg bg-muted/40 p-3 space-y-1", children: comment.isDeleted ? /* @__PURE__ */ jsx13("p", { className: "text-sm italic text-muted-foreground", children: "Comment removed" }) : /* @__PURE__ */ jsxs12(Fragment, { children: [
903
- /* @__PURE__ */ jsxs12("div", { className: "flex items-center justify-between gap-2", children: [
904
- /* @__PURE__ */ jsx13("span", { className: "text-sm font-medium text-foreground", children: comment.authorName }),
905
- /* @__PURE__ */ jsx13("span", { className: "text-xs text-muted-foreground", children: relativeTime(comment.createdAt) })
1079
+ return /* @__PURE__ */ jsxs14("div", { className: `${isReply ? "ml-8 border-l-2 border-border pl-4" : ""}`, children: [
1080
+ /* @__PURE__ */ jsx15("div", { className: "rounded-lg bg-muted/40 p-3 space-y-1", children: comment.isDeleted ? /* @__PURE__ */ jsx15("p", { className: "text-sm italic text-muted-foreground", children: "Comment removed" }) : /* @__PURE__ */ jsxs14(Fragment, { children: [
1081
+ /* @__PURE__ */ jsxs14("div", { className: "flex items-center justify-between gap-2", children: [
1082
+ /* @__PURE__ */ jsx15("span", { className: "text-sm font-medium text-foreground", children: comment.authorName }),
1083
+ /* @__PURE__ */ jsx15("span", { className: "text-xs text-muted-foreground", children: relativeTime(comment.createdAt) })
906
1084
  ] }),
907
- /* @__PURE__ */ jsx13("p", { className: "text-sm text-foreground whitespace-pre-wrap break-words", children: comment.body }),
908
- /* @__PURE__ */ jsxs12("div", { className: "flex gap-3 pt-1", children: [
909
- canReply && /* @__PURE__ */ jsx13(
1085
+ /* @__PURE__ */ jsx15("p", { className: "text-sm text-foreground whitespace-pre-wrap break-words", children: comment.body }),
1086
+ /* @__PURE__ */ jsxs14("div", { className: "flex gap-3 pt-1", children: [
1087
+ canReply && /* @__PURE__ */ jsx15(
910
1088
  "button",
911
1089
  {
912
1090
  onClick: () => setShowReplyForm((v) => !v),
@@ -914,7 +1092,7 @@ function CommentItem({
914
1092
  children: showReplyForm ? "Cancel" : "Reply"
915
1093
  }
916
1094
  ),
917
- canDelete && /* @__PURE__ */ jsx13(
1095
+ canDelete && /* @__PURE__ */ jsx15(
918
1096
  "button",
919
1097
  {
920
1098
  onClick: handleDelete,
@@ -925,7 +1103,7 @@ function CommentItem({
925
1103
  )
926
1104
  ] })
927
1105
  ] }) }),
928
- showReplyForm && /* @__PURE__ */ jsx13("div", { className: "mt-2 ml-2", children: /* @__PURE__ */ jsx13(
1106
+ showReplyForm && /* @__PURE__ */ jsx15("div", { className: "mt-2 ml-2", children: /* @__PURE__ */ jsx15(
929
1107
  CommentForm,
930
1108
  {
931
1109
  articleSlug,
@@ -937,7 +1115,7 @@ function CommentItem({
937
1115
  onCancel: () => setShowReplyForm(false)
938
1116
  }
939
1117
  ) }),
940
- replies.length > 0 && /* @__PURE__ */ jsx13("div", { className: "mt-2 space-y-2", children: replies.map((reply) => /* @__PURE__ */ jsx13(
1118
+ replies.length > 0 && /* @__PURE__ */ jsx15("div", { className: "mt-2 space-y-2", children: replies.map((reply) => /* @__PURE__ */ jsx15(
941
1119
  CommentItem,
942
1120
  {
943
1121
  comment: __spreadProps(__spreadValues({}, reply), { replies: [] }),
@@ -952,7 +1130,7 @@ function CommentItem({
952
1130
  }
953
1131
 
954
1132
  // src/CommentThread.tsx
955
- import { jsx as jsx14 } from "react/jsx-runtime";
1133
+ import { jsx as jsx16 } from "react/jsx-runtime";
956
1134
  function CommentThread({
957
1135
  comments,
958
1136
  articleSlug,
@@ -960,9 +1138,9 @@ function CommentThread({
960
1138
  onRefresh
961
1139
  }) {
962
1140
  if (comments.length === 0) {
963
- return /* @__PURE__ */ jsx14("p", { className: "text-sm text-muted-foreground text-center py-6", children: "No comments yet. Be the first to share your thoughts." });
1141
+ return /* @__PURE__ */ jsx16("p", { className: "text-sm text-muted-foreground text-center py-6", children: "No comments yet. Be the first to share your thoughts." });
964
1142
  }
965
- return /* @__PURE__ */ jsx14("div", { className: "space-y-4", children: comments.map((comment) => /* @__PURE__ */ jsx14(
1143
+ return /* @__PURE__ */ jsx16("div", { className: "space-y-4", children: comments.map((comment) => /* @__PURE__ */ jsx16(
966
1144
  CommentItem,
967
1145
  {
968
1146
  comment,
@@ -975,13 +1153,13 @@ function CommentThread({
975
1153
  }
976
1154
 
977
1155
  // src/CommentsSection.tsx
978
- import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
1156
+ import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
979
1157
  function CommentsSection({ articleSlug, config }) {
980
1158
  var _a, _b, _c, _d, _e, _f;
981
1159
  const { data: session, status } = useSession();
982
- const [comments, setComments] = useState6([]);
983
- const [loading, setLoading] = useState6(true);
984
- const [fetchError, setFetchError] = useState6(null);
1160
+ const [comments, setComments] = useState7([]);
1161
+ const [loading, setLoading] = useState7(true);
1162
+ const [fetchError, setFetchError] = useState7(null);
985
1163
  const perArticleEnabled = (_b = (_a = config.perArticleOverride) == null ? void 0 : _a[articleSlug]) != null ? _b : true;
986
1164
  const enabled = config.enabled && perArticleEnabled;
987
1165
  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;
@@ -1007,10 +1185,10 @@ function CommentsSection({ articleSlug, config }) {
1007
1185
  if (!enabled) return null;
1008
1186
  const count = comments.length;
1009
1187
  const label = count === 1 ? "1 comment" : `${count} comments`;
1010
- return /* @__PURE__ */ jsxs13("section", { "aria-label": "Comments", className: "mt-12 pt-8 border-t border-border space-y-6", children: [
1011
- /* @__PURE__ */ jsx15("h2", { className: "text-xl font-semibold text-foreground", children: loading ? "Comments" : label }),
1012
- status === "authenticated" ? /* @__PURE__ */ jsx15(CommentForm, { articleSlug, onSuccess: fetchComments }) : /* @__PURE__ */ jsxs13("p", { className: "text-sm text-muted-foreground", children: [
1013
- /* @__PURE__ */ jsx15(
1188
+ return /* @__PURE__ */ jsxs15("section", { "aria-label": "Comments", className: "mt-12 pt-8 border-t border-border space-y-6", children: [
1189
+ /* @__PURE__ */ jsx17("h2", { className: "text-xl font-semibold text-foreground", children: loading ? "Comments" : label }),
1190
+ status === "authenticated" ? /* @__PURE__ */ jsx17(CommentForm, { articleSlug, onSuccess: fetchComments }) : /* @__PURE__ */ jsxs15("p", { className: "text-sm text-muted-foreground", children: [
1191
+ /* @__PURE__ */ jsx17(
1014
1192
  "button",
1015
1193
  {
1016
1194
  onClick: () => signIn(),
@@ -1021,8 +1199,8 @@ function CommentsSection({ articleSlug, config }) {
1021
1199
  " ",
1022
1200
  "to join the discussion."
1023
1201
  ] }),
1024
- fetchError && /* @__PURE__ */ jsx15("p", { className: "text-sm text-destructive", children: fetchError }),
1025
- loading ? /* @__PURE__ */ jsx15("p", { className: "text-sm text-muted-foreground", children: "Loading comments\u2026" }) : /* @__PURE__ */ jsx15(
1202
+ fetchError && /* @__PURE__ */ jsx17("p", { className: "text-sm text-destructive", children: fetchError }),
1203
+ loading ? /* @__PURE__ */ jsx17("p", { className: "text-sm text-muted-foreground", children: "Loading comments\u2026" }) : /* @__PURE__ */ jsx17(
1026
1204
  CommentThread,
1027
1205
  {
1028
1206
  comments,
@@ -1037,8 +1215,10 @@ export {
1037
1215
  ArticleCard,
1038
1216
  ArticleCategoryGrid,
1039
1217
  ArticleDetailHero,
1218
+ ArticleNavigation,
1040
1219
  ArticleSchema,
1041
1220
  ArticleSearchBar,
1221
+ ArticleSocialShare,
1042
1222
  ArticlesHero,
1043
1223
  ArticlesPage,
1044
1224
  BreadcrumbSchema,