diff --git a/components/versions/copy-button.js b/components/versions/copy-button.js
new file mode 100644
index 0000000..bb49890
--- /dev/null
+++ b/components/versions/copy-button.js
@@ -0,0 +1,130 @@
+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 ContentCopyIcon from '@mui/icons-material/ContentCopy'
+import CheckIcon from '@mui/icons-material/Check'
+
+export default function CopyButton({
+ content,
+ label = 'Copier',
+ size = 'small',
+ hasSnackbarVisible = true,
+ onCopySuccess = null,
+ onCopyError = null
+}) {
+ const [copied, setCopied] = useState(false)
+ const [snackbar, setSnackbar] = useState({open: false, message: '', severity: 'success'})
+
+ const handleCopy = async () => {
+ try {
+ // Modern clipboard API with fallback
+ if (navigator.clipboard && window.isSecureContext) {
+ await navigator.clipboard.writeText(content)
+ } else {
+ // Fallback for older browsers or non-HTTPS
+ const textArea = document.createElement('textarea')
+ textArea.value = content
+ 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
+ setCopied(true)
+ setTimeout(() => setCopied(false), 2000)
+
+ if (hasSnackbarVisible) {
+ setSnackbar({
+ open: true,
+ message: 'Contenu copiƩ dans le presse-papier',
+ severity: 'success'
+ })
+ }
+
+ if (onCopySuccess) {
+ onCopySuccess()
+ }
+ } catch (error) {
+ console.error('Failed to copy to clipboard:', error)
+
+ if (hasSnackbarVisible) {
+ setSnackbar({
+ open: true,
+ message: 'Impossible de copier le contenu',
+ severity: 'error'
+ })
+ }
+
+ if (onCopyError) {
+ onCopyError(error)
+ }
+ }
+ }
+
+ const handleCloseSnackbar = () => {
+ setSnackbar(prev => ({...prev, open: false}))
+ }
+
+ return (
+ <>
+
+
+ {copied ? : }
+
+
+
+ {hasSnackbarVisible && (
+
+
+ {snackbar.message}
+
+
+ )}
+ >
+ )
+}
+
+CopyButton.propTypes = {
+ content: PropTypes.string.isRequired,
+ label: PropTypes.string,
+ size: PropTypes.oneOf(['small', 'medium', 'large']),
+ hasSnackbarVisible: PropTypes.bool,
+ onCopySuccess: PropTypes.func,
+ onCopyError: PropTypes.func
+}
+