From 269d5d6c090703c65134449d18edb2bff2fe2702 Mon Sep 17 00:00:00 2001 From: SkateSpots Date: Sat, 26 Sep 2026 23:03:06 +0700 Subject: [PATCH] feat(listing): make an offer (prefilled DM) + share listing On the listing detail page, buyers get 'Make an offer' (opens the DM with the seller pre-filled with an offer message about the listing) and 'Share listing' (copies the URL). Replaces the redundant 'Message' button (Contact Seller is already in the shared trade actions). Gate: 101 tests, 0 errors/warnings, boot smoke green. --- src/pages/ListingDetailPage.tsx | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/pages/ListingDetailPage.tsx b/src/pages/ListingDetailPage.tsx index 212762f..2d62930 100644 --- a/src/pages/ListingDetailPage.tsx +++ b/src/pages/ListingDetailPage.tsx @@ -25,7 +25,6 @@ import { genUserName } from '@/lib/genUserName'; import { cn } from '@/lib/utils'; import { ArrowLeft, - MessageCircle, CheckCircle, RotateCcw, Trash2, @@ -33,6 +32,8 @@ import { MapPin, Calendar, Tag, + Handshake, + Share2, } from 'lucide-react'; /** @@ -104,6 +105,17 @@ export default function ListingDetailPage() { const lightboxImages: LightboxImage[] = item.images.map((url) => ({ url, isOwner: isOwnListing })); + const offerMessage = `Hi! I saw your listing “${item.title}” on SkateSpots and I'd like to make an offer.`; + + const handleShare = async () => { + try { + await navigator.clipboard.writeText(window.location.href); + toast({ title: 'Link copied', description: 'Share it with a skater.' }); + } catch { + toast({ title: 'Could not copy the link', variant: 'destructive' }); + } + }; + const handleRelist = async () => { try { await relist(item.event); @@ -304,15 +316,23 @@ export default function ListingDetailPage() { +