From df2efac6c3fa269781849bacee152a47f58a41d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=A1clav=20Pavl=C3=ADn?= Date: Wed, 10 Sep 2025 13:21:12 +0200 Subject: [PATCH] clean up the share button(s) --- src/components/CellList.tsx | 6 +++ src/components/CommentCard.tsx | 22 ++++++--- src/components/PostCard.tsx | 43 +++------------- src/components/PostDetail.tsx | 6 +++ src/components/PostList.tsx | 10 ++++ src/components/ui/ShareButton.tsx | 81 +++++++++++++++++++++++++++++++ 6 files changed, 124 insertions(+), 44 deletions(-) create mode 100644 src/components/ui/ShareButton.tsx diff --git a/src/components/CellList.tsx b/src/components/CellList.tsx index ad151de..d9a3d70 100644 --- a/src/components/CellList.tsx +++ b/src/components/CellList.tsx @@ -27,6 +27,7 @@ import { ModerationToggle } from './ui/moderation-toggle'; import { sortCells, SortOption } from '@/lib/utils/sorting'; import { Cell } from '@/types/forum'; import { usePending } from '@/hooks/usePending'; +import { ShareButton } from './ui/ShareButton'; // Empty State Component const EmptyState: React.FC<{ canCreateCell: boolean }> = ({ @@ -125,6 +126,11 @@ const CellItem: React.FC<{ cell: Cell }> = ({ cell }) => { {cell.activeMemberCount || 0} members + diff --git a/src/components/CommentCard.tsx b/src/components/CommentCard.tsx index 09e6ea0..020c054 100644 --- a/src/components/CommentCard.tsx +++ b/src/components/CommentCard.tsx @@ -18,6 +18,7 @@ import { TooltipContent, TooltipTrigger, } from '@/components/ui/tooltip'; +import { ShareButton } from '@/components/ui/ShareButton'; interface CommentCardProps { comment: Comment; @@ -126,13 +127,20 @@ const CommentCard: React.FC = ({ - +
+ 50 ? '...' : '')} + /> + +

diff --git a/src/components/PostCard.tsx b/src/components/PostCard.tsx index ef3d541..bc33a7d 100644 --- a/src/components/PostCard.tsx +++ b/src/components/PostCard.tsx @@ -15,7 +15,7 @@ import { AuthorDisplay } from '@/components/ui/author-display'; import { BookmarkButton } from '@/components/ui/bookmark-button'; import { LinkRenderer } from '@/components/ui/link-renderer'; import { usePending, usePendingVote } from '@/hooks/usePending'; -import { useToast } from '@/components/ui/use-toast'; +import { ShareButton } from '@/components/ui/ShareButton'; interface PostCardProps { post: Post; @@ -32,7 +32,6 @@ const PostCard: React.FC = ({ post, commentCount = 0 }) => { loading: bookmarkLoading, toggleBookmark, } = usePostBookmark(post, post.cellId); - const { toast } = useToast(); // ✅ Get pre-computed cell data const cell = cellsWithStats.find(c => c.id === post.cellId); @@ -71,33 +70,6 @@ const PostCard: React.FC = ({ post, commentCount = 0 }) => { await toggleBookmark(); }; - const handleShare = async (e: React.MouseEvent) => { - e.preventDefault(); - e.stopPropagation(); - - const postUrl = `${window.location.origin}/post/${post.id}`; - - try { - await navigator.clipboard.writeText(postUrl); - toast({ - title: 'Link copied!', - description: 'Post link has been copied to your clipboard.', - }); - } catch { - // Fallback for older browsers - const textArea = document.createElement('textarea'); - textArea.value = postUrl; - document.body.appendChild(textArea); - textArea.select(); - document.execCommand('copy'); - document.body.removeChild(textArea); - - toast({ - title: 'Link copied!', - description: 'Post link has been copied to your clipboard.', - }); - } - }; return (

@@ -207,14 +179,11 @@ const PostCard: React.FC = ({ post, commentCount = 0 }) => { syncing… )} - +
{ const { postId } = useParams<{ postId: string }>(); @@ -243,6 +244,11 @@ const PostDetail = () => { variant="ghost" showText={true} /> +

diff --git a/src/components/PostList.tsx b/src/components/PostList.tsx index e725c20..4f23932 100644 --- a/src/components/PostList.tsx +++ b/src/components/PostList.tsx @@ -14,6 +14,7 @@ import { Input } from '@/components/ui/input'; import { Textarea } from '@/components/ui/textarea'; import { Skeleton } from '@/components/ui/skeleton'; import { LinkRenderer } from '@/components/ui/link-renderer'; +import { ShareButton } from '@/components/ui/ShareButton'; import { ArrowLeft, MessageSquare, @@ -324,6 +325,15 @@ const PostList = () => { className="text-xs" showBadge={false} /> + {canModerate(cell.id) && !post.moderated && ( diff --git a/src/components/ui/ShareButton.tsx b/src/components/ui/ShareButton.tsx new file mode 100644 index 0000000..21835ef --- /dev/null +++ b/src/components/ui/ShareButton.tsx @@ -0,0 +1,81 @@ +import { Button } from '@/components/ui/button'; +import { Share2 } from 'lucide-react'; +import { cn } from '@/lib/utils'; +import { useToast } from '../ui/use-toast'; + +interface ShareButtonProps { + url: string; + title: string; + description?: string; + size?: 'sm' | 'lg'; + variant?: 'default' | 'ghost' | 'outline'; + className?: string; + showText?: boolean; +} + +export function ShareButton({ + url, + title, + description = 'Check out this post', + size = 'sm', + variant = 'ghost', + className, + showText = false, +}: ShareButtonProps) { + const { toast } = useToast(); + + const sizeClasses = { + sm: 'h-8 w-10', + lg: 'h-10 whitespace-nowrap px-4', + }; + + const iconSize = { + sm: 14, + lg: 18, + }; + + const handleShare = async (e: React.MouseEvent) => { + e.preventDefault(); + e.stopPropagation(); + + try { + await navigator.clipboard.writeText(url); + toast({ + title: 'Link copied!', + description: 'Link has been copied to your clipboard.', + }); + } catch { + // Fallback for older browsers + const textArea = document.createElement('textarea'); + textArea.value = url; + document.body.appendChild(textArea); + textArea.select(); + document.execCommand('copy'); + document.body.removeChild(textArea); + + toast({ + title: 'Link copied!', + description: 'Link has been copied to your clipboard.', + }); + } + }; + + return ( + + ); +} \ No newline at end of file