From afc5b2ae978b3d0bf212e4d56910b72f0cb691ef Mon Sep 17 00:00:00 2001 From: Anton Tranelis Date: Fri, 10 Oct 2025 16:01:02 +0200 Subject: [PATCH] refactored share-button --- .../HeaderView/ActionButtons.tsx | 121 +------------ .../HeaderView/ConnectionStatus.tsx | 4 + .../HeaderView/QRModal.tsx | 16 +- .../HeaderView/ShareButton.tsx | 171 ++++++++++++++++++ .../ItemPopupComponents/HeaderView/hooks.ts | 5 +- .../ItemPopupComponents/StartEndView.tsx | 22 +-- lib/src/types/ItemType.d.ts | 1 + 7 files changed, 194 insertions(+), 146 deletions(-) create mode 100644 lib/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView/ShareButton.tsx diff --git a/lib/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView/ActionButtons.tsx b/lib/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView/ActionButtons.tsx index 435b92bf..df9b99a4 100644 --- a/lib/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView/ActionButtons.tsx +++ b/lib/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView/ActionButtons.tsx @@ -1,20 +1,12 @@ -import { QrCodeIcon, ShareIcon } from '@heroicons/react/24/solid' +import { QrCodeIcon } from '@heroicons/react/24/solid' import { LuNavigation } from 'react-icons/lu' -import ChevronSVG from '#assets/chevron.svg' -import ClipboardSVG from '#assets/share/clipboard.svg' -import FacebookSVG from '#assets/share/facebook.svg' -import LinkedinSVG from '#assets/share/linkedin.svg' -import TelegramSVG from '#assets/share/telegram.svg' -import TwitterSVG from '#assets/share/twitter.svg' -import WhatsappSVG from '#assets/share/whatsapp.svg' -import XingSVG from '#assets/share/xing.svg' import { useMyProfile } from '#components/Map/hooks/useMyProfile' -import { useNavigationUrl, useShareLogic } from './hooks' +import { useNavigationUrl } from './hooks' +import { ShareButton } from './ShareButton' import type { Item } from '#types/Item' -import type { PlatformConfig, SharePlatformConfigs } from './types' interface ActionButtonsProps { item: Item @@ -26,46 +18,6 @@ export function ActionButtons({ item, onQrModalOpen }: ActionButtonsProps) { const { getNavigationUrl, isMobile, isIOS } = useNavigationUrl( item.position?.coordinates as [number, number] | undefined, ) - const { shareUrl, shareTitle, copyLink, getShareUrl } = useShareLogic(item) - - const platformConfigs: SharePlatformConfigs = { - facebook: { - shareUrl: 'https://www.facebook.com/sharer/sharer.php?u={url}', - icon: Facebook, - label: 'Facebook', - bgColor: '#3b5998', - }, - twitter: { - shareUrl: 'https://twitter.com/intent/tweet?text={title}:%20{url}', - icon: Twitter, - label: 'Twitter', - bgColor: '#55acee', - }, - linkedin: { - shareUrl: 'http://www.linkedin.com/shareArticle?mini=true&url={url}&title={title}', - icon: Linkedin, - label: 'LinkedIn', - bgColor: '#4875b4', - }, - whatsapp: { - shareUrl: 'https://api.whatsapp.com/send?text={title}%20{url}', - icon: Whatsapp, - label: 'WhatsApp', - bgColor: '#25D366', - }, - telegram: { - shareUrl: 'https://t.me/share/url?url={url}&text={title}', - icon: Telegram, - label: 'Telegram', - bgColor: '#0088cc', - }, - xing: { - shareUrl: 'https://www.xing-share.com/app/user?op=share;sc_p=xing-share;url={url}', - icon: Xing, - label: 'Xing', - bgColor: '#026466', - }, - } return ( <> @@ -92,72 +44,7 @@ export function ActionButtons({ item, onQrModalOpen }: ActionButtonsProps) { )} - {myProfile.myProfile?.id !== item.id && ( -
-
- -
- -
- )} + {myProfile.myProfile?.id !== item.id && } ) } diff --git a/lib/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView/ConnectionStatus.tsx b/lib/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView/ConnectionStatus.tsx index b3309ccf..5fae3b2d 100644 --- a/lib/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView/ConnectionStatus.tsx +++ b/lib/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView/ConnectionStatus.tsx @@ -23,6 +23,10 @@ export function ConnectionStatus({ item }: ConnectionStatusProps) { r.related_items_id === myProfile.myProfile?.id, ) + if (!item.layer?.itemType.show_cta_button) { + return null + } + if (isConnected) { return

✅ Connected

} diff --git a/lib/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView/QRModal.tsx b/lib/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView/QRModal.tsx index c1dd7ccf..6702bd3e 100644 --- a/lib/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView/QRModal.tsx +++ b/lib/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView/QRModal.tsx @@ -1,9 +1,9 @@ import QRCode from 'react-qr-code' -import ClipboardSVG from '#assets/share/clipboard.svg' import DialogModal from '#components/Templates/DialogModal' import { useShareLogic } from './hooks' +import { ShareButton } from './ShareButton' import type { Item } from '#types/Item' @@ -14,7 +14,7 @@ interface QRModalProps { } export function QRModal({ item, isOpen, onClose }: QRModalProps) { - const { inviteLink, copyLink } = useShareLogic(item) + const { inviteLink } = useShareLogic(item) return (
e.stopPropagation()} className='tw:text-center tw:p-4'> -

Share your profile with others to expand your network.

+

Share your Profile to expand your Network!

-
+
{inviteLink} - +
diff --git a/lib/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView/ShareButton.tsx b/lib/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView/ShareButton.tsx new file mode 100644 index 00000000..f843d4a1 --- /dev/null +++ b/lib/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView/ShareButton.tsx @@ -0,0 +1,171 @@ +import { useRef } from 'react' + +import { ShareIcon } from '@heroicons/react/24/solid' + +import ChevronSVG from '#assets/chevron.svg' +import ClipboardSVG from '#assets/share/clipboard.svg' +import FacebookSVG from '#assets/share/facebook.svg' +import LinkedinSVG from '#assets/share/linkedin.svg' +import TelegramSVG from '#assets/share/telegram.svg' +import TwitterSVG from '#assets/share/twitter.svg' +import WhatsappSVG from '#assets/share/whatsapp.svg' +import XingSVG from '#assets/share/xing.svg' + +import { useShareLogic } from './hooks' + +import type { Item } from '#types/Item' +import type { PlatformConfig, SharePlatformConfigs } from './types' + +interface ShareButtonProps { + item: Item + dropdownDirection?: 'up' | 'down' +} + +export function ShareButton({ item, dropdownDirection = 'down' }: ShareButtonProps) { + const { shareUrl, shareTitle, copyLink, getShareUrl } = useShareLogic(item) + const detailsRef = useRef(null) + + const closeDropdown = () => { + if (detailsRef.current) { + detailsRef.current.open = false + } + } + + const handleCopyLink = () => { + copyLink() + closeDropdown() + } + + const handleNativeShare = async () => { + if (navigator.share) { + try { + await navigator.share({ + title: shareTitle, + url: shareUrl, + }) + closeDropdown() + } catch (error) { + // User cancelled or error occurred + console.log('Share cancelled or failed:', error) + } + } + } + + const canUseNativeShare = typeof navigator !== 'undefined' && navigator.share + + const platformConfigs: SharePlatformConfigs = { + facebook: { + shareUrl: 'https://www.facebook.com/sharer/sharer.php?u={url}', + icon: Facebook, + label: 'Facebook', + bgColor: '#3b5998', + }, + twitter: { + shareUrl: 'https://twitter.com/intent/tweet?text={title}:%20{url}', + icon: Twitter, + label: 'Twitter', + bgColor: '#55acee', + }, + linkedin: { + shareUrl: 'http://www.linkedin.com/shareArticle?mini=true&url={url}&title={title}', + icon: Linkedin, + label: 'LinkedIn', + bgColor: '#4875b4', + }, + whatsapp: { + shareUrl: 'https://api.whatsapp.com/send?text={title}%20{url}', + icon: Whatsapp, + label: 'WhatsApp', + bgColor: '#25D366', + }, + telegram: { + shareUrl: 'https://t.me/share/url?url={url}&text={title}', + icon: Telegram, + label: 'Telegram', + bgColor: '#0088cc', + }, + xing: { + shareUrl: 'https://www.xing-share.com/app/user?op=share;sc_p=xing-share;url={url}', + icon: Xing, + label: 'Xing', + bgColor: '#026466', + }, + } + + const dropdownClass = dropdownDirection === 'up' ? 'tw:dropdown-top' : '' + + // If native share is available, render a simple button instead of dropdown + if (canUseNativeShare) { + return ( + + ) + } + + // Otherwise, render the dropdown with manual share options + return ( +
+ + + + +
+ ) +} diff --git a/lib/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView/hooks.ts b/lib/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView/hooks.ts index 9034ab53..e2cec281 100644 --- a/lib/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView/hooks.ts +++ b/lib/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView/hooks.ts @@ -35,10 +35,7 @@ export const useNavigationUrl = (coordinates?: [number, number]) => { export const useShareLogic = (item?: Item) => { const shareUrl = window.location.href const shareTitle = item?.name ?? 'Utopia Map Item' - const inviteLink = - item?.secrets && item.secrets.length > 0 - ? `${window.location.origin}/invite/${item.secrets[0].secret}` - : shareUrl + const inviteLink = shareUrl const copyLink = () => { navigator.clipboard diff --git a/lib/src/Components/Map/Subcomponents/ItemPopupComponents/StartEndView.tsx b/lib/src/Components/Map/Subcomponents/ItemPopupComponents/StartEndView.tsx index 74da45bc..7402053d 100644 --- a/lib/src/Components/Map/Subcomponents/ItemPopupComponents/StartEndView.tsx +++ b/lib/src/Components/Map/Subcomponents/ItemPopupComponents/StartEndView.tsx @@ -8,25 +8,19 @@ import type { Item } from '#types/Item' */ export const StartEndView = ({ item }: { item?: Item }) => { return ( -
-
- -