'use client' import {useState, useEffect, useRef} from 'react' import PropTypes from 'prop-types' import Box from '@mui/material/Box' import Container from '@mui/material/Container' import Typography from '@mui/material/Typography' import Button from '@mui/material/Button' import Paper from '@mui/material/Paper' import Chip from '@mui/material/Chip' 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 ArrowBackIcon from '@mui/icons-material/ArrowBack' import ShareIcon from '@mui/icons-material/Share' import {useRouter} from 'next/navigation' import SessionExpired from '../session/session-expired.js' import AuthAlert from '../auth-form/auth-alert.js' import {Loading} from '../loading.js' import Footer from '../footer.js' import VoteButtons from './vote-buttons.js' import CopyButton from './copy-button.js' import ExportPdfButton from './export-pdf-button.js' import PrintButton from './print-button.js' import VersionComparison from './version-comparison.js' import {getVersion, compareVersion, getVoteCounts} from '@/lib/directus.js' import {formatDate} from '@/lib/format.js' export default function VersionPage({session, versionId, viewMode}) { const router = useRouter() const {accessToken, userId} = session.user const countdownRef = useRef() const [versionData, setVersionData] = useState(null) const [versionCompare, setVersionCompare] = useState(null) const [loading, setLoading] = useState(true) const [error, setError] = useState('') const [isErrorAlertOpen, setIsErrorAlertOpen] = useState(false) const [snackbar, setSnackbar] = useState({open: false, message: '', severity: 'success'}) const [voteRefreshKey, setVoteRefreshKey] = useState(0) const [voteCounts, setVoteCounts] = useState(null) useEffect(() => { async function fetchVersionData() { try { setLoading(true) // Fetch version details const version = await getVersion({ accessToken, userId, versionId }) setVersionData(version) // Fetch comparison data (needed for outdated status even if not in comparison mode) const comparison = await compareVersion({ accessToken, userId, versionId, countdownRef, setError, setIsErrorAlertOpen }) if (comparison) { setVersionCompare({...comparison, versionId}) } const counts = await getVoteCounts({ accessToken, versionId }) setVoteCounts(counts) } catch (error) { console.error('Failed to fetch version:', error) setError('Impossible de charger cette version') setIsErrorAlertOpen(true) } finally { setLoading(false) } } fetchVersionData() }, [accessToken, userId, versionId]) const handleBack = () => { router.push('/dashboard') } const handleVoteResult = async result => { setSnackbar({ open: true, message: result.message, severity: result.success ? 'success' : 'error' }) // Force refresh of both VoteButtons components by changing the key setVoteRefreshKey(prev => prev + 1) if (result.success) { const counts = await getVoteCounts({ accessToken, versionId }) setVoteCounts(counts) } } const handleCloseSnackbar = () => { setSnackbar(prev => ({...prev, open: false})) } const handleShare = async () => { const url = window.location.href try { if (navigator.share) { // Use native share API if available await navigator.share({ title: `Version: ${versionData?.name || 'Version'}`, text: 'Découvrez cette version sur Konstitisyon.nu', url }) setSnackbar({ open: true, message: 'Version partagée', severity: 'success' }) } else { // Fallback: copy URL to clipboard 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') } } setSnackbar({ open: true, message: 'Lien copié dans le presse-papier', severity: 'success' }) } } catch (error) { console.error('Failed to share:', error) setSnackbar({ open: true, message: 'Impossible de partager cette version', severity: 'error' }) } } if (loading) { return ( ) } if (error && !versionData) { return ( Version introuvable ) } const createdAt = new Date(versionData.date_created) const threeDaysAgo = new Date(Date.now() - (3 * 24 * 60 * 60 * 1000)) const isVoteDisabled = createdAt < threeDaysAgo const authorName = versionData.user_created?.split('-')[0] || 'Système' return ( {error && ( )} {/* Header */} {/* Version Info */} {versionData.name} Créée par @{authorName} le {formatDate(versionData.date_created, 'PPpp')} {!isVoteDisabled && ( )} {/* Content */} {viewMode === 'comparison' && versionCompare ? ( ) : ( Contenu {versionData.delta?.contenu || 'Aucun contenu disponible'} )}