'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 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
})
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
} onClick={handleBack}>
Retour au tableau de bord
)
}
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 */}
}
variant='outlined'
onClick={handleBack}
>
Retour
{/* 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'}
)}
{snackbar.message}
)
}
VersionPage.propTypes = {
session: PropTypes.object.isRequired,
versionId: PropTypes.string.isRequired,
viewMode: PropTypes.oneOf(['comparison', 'content']).isRequired
}