From 9664524d0857c9bea960fa1375613f12e3e9a381 Mon Sep 17 00:00:00 2001 From: Pranjal Yadav Date: Sun, 14 Dec 2025 01:16:10 +0530 Subject: [PATCH 1/4] feat(article): add social share buttons with pre-filled content --- app/a/[slug]/BlogPostClient.tsx | 101 ++++++++++++++++++++++++++++++-- 1 file changed, 95 insertions(+), 6 deletions(-) diff --git a/app/a/[slug]/BlogPostClient.tsx b/app/a/[slug]/BlogPostClient.tsx index 1cc923c..16a0e9d 100644 --- a/app/a/[slug]/BlogPostClient.tsx +++ b/app/a/[slug]/BlogPostClient.tsx @@ -29,15 +29,15 @@ export default function BlogPostPage({ post }: { post: BlogPost }) { {/* Hero Image */} {post.image && (
- {post.title}
@@ -67,6 +67,95 @@ export default function BlogPostPage({ post }: { post: BlogPost }) {
+ {/* Social Share Buttons */} +
+

Share this article:

+
+ {/* Twitter/X Share */} + + + {/* LinkedIn Share */} + + + {/* Facebook Share */} + + + {/* Copy Link */} + +
+
+
From 3b5eeaa2087b02e15e01392d64babcdef9a58331 Mon Sep 17 00:00:00 2001 From: Pranjal Yadav Date: Sun, 14 Dec 2025 01:51:35 +0530 Subject: [PATCH 2/4] refactor(article): address CodeRabbit feedback for share buttons --- app/a/[slug]/BlogPostClient.tsx | 59 ++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 16 deletions(-) diff --git a/app/a/[slug]/BlogPostClient.tsx b/app/a/[slug]/BlogPostClient.tsx index 16a0e9d..ae53774 100644 --- a/app/a/[slug]/BlogPostClient.tsx +++ b/app/a/[slug]/BlogPostClient.tsx @@ -1,5 +1,6 @@ "use client" +import { useState } from "react" import Link from "next/link" import { ArrowLeft, Calendar, User } from "lucide-react" import Image from "next/image" @@ -8,6 +9,8 @@ import Footer from "@/components/footer" import { BlogPost } from "@/lib/blog" export default function BlogPostPage({ post }: { post: BlogPost }) { + const [copied, setCopied] = useState(false) + return (
{/* Header */} @@ -73,14 +76,18 @@ export default function BlogPostPage({ post }: { post: BlogPost }) {
{/* Twitter/X Share */}
From 0098224dacb911172c5990fa54df6e9e0f917c03 Mon Sep 17 00:00:00 2001 From: Pranjal Yadav Date: Sun, 14 Dec 2025 02:16:38 +0530 Subject: [PATCH 3/4] fix(article): address final CodeRabbit security and cleanup feedback --- app/a/[slug]/BlogPostClient.tsx | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/app/a/[slug]/BlogPostClient.tsx b/app/a/[slug]/BlogPostClient.tsx index ae53774..ce5723b 100644 --- a/app/a/[slug]/BlogPostClient.tsx +++ b/app/a/[slug]/BlogPostClient.tsx @@ -1,6 +1,6 @@ "use client" -import { useState } from "react" +import { useState, useEffect, useRef } from "react" import Link from "next/link" import { ArrowLeft, Calendar, User } from "lucide-react" import Image from "next/image" @@ -10,6 +10,13 @@ import { BlogPost } from "@/lib/blog" export default function BlogPostPage({ post }: { post: BlogPost }) { const [copied, setCopied] = useState(false) + const copiedTimeoutRef = useRef(null) + + useEffect(() => { + return () => { + if (copiedTimeoutRef.current != null) window.clearTimeout(copiedTimeoutRef.current) + } + }, []) return (
@@ -33,11 +40,7 @@ export default function BlogPostPage({ post }: { post: BlogPost }) { {post.image && (
{post.title} { + if (!window.isSecureContext || !navigator.clipboard?.writeText) { + alert('Copy is only available on HTTPS. Please copy the URL from the address bar.') + return + } navigator.clipboard.writeText(window.location.href) .then(() => { + if (copiedTimeoutRef.current != null) window.clearTimeout(copiedTimeoutRef.current) setCopied(true) - setTimeout(() => setCopied(false), 2000) + copiedTimeoutRef.current = window.setTimeout(() => setCopied(false), 2000) }) .catch((err) => { console.error('Failed to copy:', err) From 20d24653b1d34daa29796fe0dbb4306de4bd0979 Mon Sep 17 00:00:00 2001 From: Pranjal Yadav Date: Sun, 14 Dec 2025 02:27:40 +0530 Subject: [PATCH 4/4] chore(article): address CodeRabbit accessibility nitpicks --- app/a/[slug]/BlogPostClient.tsx | 7 ++++++- app/globals.css | 13 +++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/app/a/[slug]/BlogPostClient.tsx b/app/a/[slug]/BlogPostClient.tsx index ce5723b..3af4a8c 100644 --- a/app/a/[slug]/BlogPostClient.tsx +++ b/app/a/[slug]/BlogPostClient.tsx @@ -155,7 +155,7 @@ export default function BlogPostPage({ post }: { post: BlogPost }) { type="button" onClick={() => { if (!window.isSecureContext || !navigator.clipboard?.writeText) { - alert('Copy is only available on HTTPS. Please copy the URL from the address bar.') + alert('Copy is only available in a secure context (HTTPS or localhost). Please copy the URL from the address bar.') return } navigator.clipboard.writeText(window.location.href) @@ -191,6 +191,11 @@ export default function BlogPostPage({ post }: { post: BlogPost }) {
+ {/* Screen reader announcement for copy feedback */} +
+ {copied && "Link copied to clipboard"} +
+
diff --git a/app/globals.css b/app/globals.css index ac68442..c968533 100644 --- a/app/globals.css +++ b/app/globals.css @@ -10,6 +10,19 @@ body { .text-balance { text-wrap: balance; } + + /* Screen reader only - hides content visually but keeps it accessible to screen readers */ + .sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; + } } @layer base {