Files
konstitisyon.nu/components/versions/share-button.js
T

138 lines
3.8 KiB
JavaScript

import {useState} from 'react'
import PropTypes from 'prop-types'
import IconButton from '@mui/material/IconButton'
import Tooltip from '@mui/material/Tooltip'
import Snackbar from '@mui/material/Snackbar'
import Alert from '@mui/material/Alert'
import ShareIcon from '@mui/icons-material/Share'
import LinkIcon from '@mui/icons-material/Link'
export default function ShareButton({
versionId,
versionName = 'Version',
size = 'small',
hasSnackbarVisible = true,
onShareSuccess = null,
onShareError = null
}) {
const [shared, setShared] = useState(false)
const [snackbar, setSnackbar] = useState({open: false, message: '', severity: 'success'})
const handleShare = async () => {
const url = `${window.location.origin}/dashboard/versions/${versionId}`
try {
if (navigator.share) {
// Use native share API if available
await navigator.share({
title: `Version: ${versionName}`,
text: 'Découvrez cette version sur Konstitisyon.nu',
url
})
} else if (navigator.clipboard && window.isSecureContext) {
await navigator.clipboard.writeText(url)
} else {
// Fallback for older browsers
const textArea = document.createElement('textarea')
textArea.value = url
textArea.style.position = 'fixed'
textArea.style.left = '-999999px'
textArea.style.top = '-999999px'
document.body.append(textArea)
textArea.focus()
textArea.select()
const result = document.execCommand('copy')
textArea.remove()
if (!result) {
throw new Error('Copy command failed')
}
}
// Success feedback
setShared(true)
setTimeout(() => setShared(false), 2000)
if (hasSnackbarVisible) {
setSnackbar({
open: true,
message: navigator.share ? 'Version partagée' : 'Lien copié dans le presse-papier',
severity: 'success'
})
}
if (onShareSuccess) {
onShareSuccess()
}
} catch (error) {
console.error('Failed to share:', error)
if (hasSnackbarVisible) {
setSnackbar({
open: true,
message: 'Impossible de partager cette version',
severity: 'error'
})
}
if (onShareError) {
onShareError(error)
}
}
}
const handleCloseSnackbar = () => {
setSnackbar(prev => ({...prev, open: false}))
}
return (
<>
<Tooltip title={shared ? 'Partagé !' : 'Partager cette version'}>
<IconButton
size={size}
aria-label='Partager cette version'
sx={{
color: shared ? 'success.main' : 'text.secondary',
'&:hover': {
color: shared ? 'success.dark' : 'primary.main',
backgroundColor: shared ? 'success.light' : 'action.hover'
},
transition: 'all 0.2s ease-in-out'
}}
onClick={handleShare}
>
{shared ? <LinkIcon /> : <ShareIcon />}
</IconButton>
</Tooltip>
{hasSnackbarVisible && (
<Snackbar
open={snackbar.open}
autoHideDuration={3000}
anchorOrigin={{vertical: 'bottom', horizontal: 'center'}}
onClose={handleCloseSnackbar}
>
<Alert
variant='filled'
severity={snackbar.severity}
sx={{width: '100%'}}
onClose={handleCloseSnackbar}
>
{snackbar.message}
</Alert>
</Snackbar>
)}
</>
)
}
ShareButton.propTypes = {
versionId: PropTypes.string.isRequired,
versionName: PropTypes.string,
size: PropTypes.oneOf(['small', 'medium', 'large']),
hasSnackbarVisible: PropTypes.bool,
onShareSuccess: PropTypes.func,
onShareError: PropTypes.func
}