'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 VersionComparison from './version-comparison.js' import {getVersion, compareVersion} 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) useEffect(() => { async function fetchVersionData() { try { setLoading(true) // Fetch version details const version = await getVersion({ accessToken, userId, versionId }) setVersionData(version) // If in comparison mode, also fetch comparison data if (viewMode === 'comparison') { const comparison = await compareVersion({ accessToken, userId, versionId, countdownRef, setError, setIsErrorAlertOpen }) if (comparison) { setVersionCompare({...comparison, versionId}) } } } catch (error) { console.error('Failed to fetch version:', error) setError('Impossible de charger cette version') setIsErrorAlertOpen(true) } finally { setLoading(false) } } fetchVersionData() }, [accessToken, userId, versionId, viewMode]) const handleBack = () => { router.push('/dashboard') } const handleVoteResult = 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) } 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.la', url }) } else { // Fallback: copy URL to clipboard await navigator.clipboard.writeText(url) // Could show a toast notification here } } catch (error) { console.error('Failed to share:', 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'} )}