diff --git a/packages/synapse-react-client/src/components/SharePageLinkButton/SharePageLinkButton.stories.tsx b/packages/synapse-react-client/src/components/SharePageLinkButton/SharePageLinkButton.stories.tsx new file mode 100644 index 0000000000..6adf3ddd7d --- /dev/null +++ b/packages/synapse-react-client/src/components/SharePageLinkButton/SharePageLinkButton.stories.tsx @@ -0,0 +1,23 @@ +import { Meta, StoryObj } from '@storybook/react' +import SharePageLinkButton from './SharePageLinkButton' + +const meta = { + title: 'UI/SharePageLinkButton', + component: SharePageLinkButton, +} satisfies Meta +export default meta +type Story = StoryObj + +export const SharePageLinkButtonStory: Story = { + args: { + buttonProps: { + sx: { position: 'fixed', right: '20px' }, + }, + }, + parameters: { + stack: 'mock', + msw: { + handlers: [], + }, + }, +} diff --git a/packages/synapse-react-client/src/components/SharePageLinkButton/SharePageLinkButton.tsx b/packages/synapse-react-client/src/components/SharePageLinkButton/SharePageLinkButton.tsx new file mode 100644 index 0000000000..9dc657c7a0 --- /dev/null +++ b/packages/synapse-react-client/src/components/SharePageLinkButton/SharePageLinkButton.tsx @@ -0,0 +1,71 @@ +import React, { useCallback } from 'react' +import { useMutation } from '@tanstack/react-query' +import { displayToast } from '../ToastMessage' +import IconSvg from '../IconSvg' +import { Button, ButtonProps } from '@mui/material' + +export type SharePageLinkButtonProps = { + shortIoPublicApiKey?: string + domain?: string + buttonProps?: ButtonProps +} + +export const SharePageLinkButton: React.FunctionComponent< + SharePageLinkButtonProps +> = ({ shortIoPublicApiKey, domain = 'sageb.io', buttonProps }) => { + const copyToClipboard = useCallback((value: string) => { + navigator.clipboard.writeText(value).then(() => { + displayToast('Page URL copied to the clipboard', 'success') + }) + }, []) + // create short io link (if not already created) + const { mutate: createShortUrl } = useMutation({ + mutationFn: async () => { + if (!shortIoPublicApiKey) { + return window.location.href + } else { + const response = await fetch('https://api.short.io/links/public', { + method: 'POST', + headers: { + Authorization: shortIoPublicApiKey, + 'Content-Type': 'application/json', + Accept: 'application/json', + }, + body: JSON.stringify({ + originalURL: window.location.href, + domain: domain, + }), + }) + + if (!response.ok) { + const responseText = await response.text() + throw new Error(responseText) + } + const jsonResponse = await response.json() + return jsonResponse.shortURL + } + }, + onSuccess: data => { + copyToClipboard(data) + }, + onError: error => { + console.error(error) + copyToClipboard(window.location.href) + }, + }) + + return ( + + ) +} + +export default SharePageLinkButton diff --git a/packages/synapse-react-client/src/components/SharePageLinkButton/index.ts b/packages/synapse-react-client/src/components/SharePageLinkButton/index.ts new file mode 100644 index 0000000000..d8e5a130b2 --- /dev/null +++ b/packages/synapse-react-client/src/components/SharePageLinkButton/index.ts @@ -0,0 +1,4 @@ +import SharePageLinkButton from './SharePageLinkButton' +import type { SharePageLinkButtonProps } from './SharePageLinkButton' +export { SharePageLinkButton, SharePageLinkButtonProps } +export default SharePageLinkButton