= ({
-
+
+ 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