import {useRef, useState, useEffect} from 'react'
import PropTypes from 'prop-types'
import Box from '@mui/material/Box'
import Typography from '@mui/material/Typography'
import IconButton from '@mui/material/IconButton'
import Collapse from '@mui/material/Collapse'
import Snackbar from '@mui/material/Snackbar'
import Alert from '@mui/material/Alert'
import CompareArrowsIcon from '@mui/icons-material/CompareArrows'
import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
import ExpandLessIcon from '@mui/icons-material/ExpandLess'
import SessionExpired from '../session/session-expired.js'
import VersionDialog from './version-dialog.js'
import VoteButtons from './vote-buttons.js'
import CopyButton from './copy-button.js'
import {formatDate} from '@/lib/format.js'
import {compareVersion} from '@/lib/directus.js'
function getStatusColor(isOutdated, index) {
if (isOutdated) {
return '#D32F2F'
}
if (index === 0) {
return '#1976D2'
}
return '#9E9E9E'
}
function VersionItem({
version,
index,
accessToken,
userId,
countdownRef,
setError,
setIsErrorAlertOpen,
setIsOpenComparison,
setVersionCompare,
onVoteResult
}) {
const [isOutdated, setIsOutdated] = useState(false)
const [expanded, setExpanded] = useState(false)
useEffect(() => {
async function fetchStatus() {
try {
const comparisonData = await compareVersion({
accessToken,
userId,
versionId: version.id,
countdownRef,
setError,
setIsErrorAlertOpen
})
if (comparisonData) {
setIsOutdated(comparisonData.outdated)
}
} catch {
setIsOutdated(false)
}
}
fetchStatus()
}, [version.id, accessToken, userId, countdownRef, setError, setIsErrorAlertOpen])
const statusColor = getStatusColor(isOutdated, index)
const createdAt = new Date(version.date_created)
const threeDaysAgo = new Date(Date.now() - (3 * 24 * 60 * 60 * 1000))
const isVoteDisabled = createdAt < threeDaysAgo || isOutdated
const handleCompare = async () => {
const comparisonData = await compareVersion({
accessToken,
userId,
versionId: version.id,
countdownRef,
setError,
setIsErrorAlertOpen
})
if (comparisonData) {
setVersionCompare({...comparisonData, versionId: version.id})
setIsOpenComparison(true)
}
}
return (
{/* Status indicator */}
{/* Content */}
{/* Header row */}
{version.name}
{formatDate(version.date_created, 'dd/MM/yy HH:mm')}
{/* Actions */}
setExpanded(!expanded)}>
{expanded ? : }
{/* Expanded content */}
{/* Preview */}
{version.delta?.contenu && (
{version.delta.contenu}
)}
{/* Actions row */}
)
}
export default function VersionTimeline({
data,
accessToken,
userId,
setError,
setIsErrorAlertOpen,
onVoteSuccess
}) {
const countdownRef = useRef()
const [isOpenComparison, setIsOpenComparison] = useState(false)
const [versionCompare, setVersionCompare] = useState(null)
const [snackbar, setSnackbar] = useState({open: false, message: '', severity: 'success'})
const versionData = data.find(({id}) => id === versionCompare?.versionId)
const handleVoteResult = (result, versionId) => {
setSnackbar({
open: true,
message: result.message,
severity: result.success ? 'success' : 'error'
})
if (result.success && onVoteSuccess && versionId) {
onVoteSuccess(versionId)
}
}
return (
<>
{data.map((version, index) => (
handleVoteResult(result, version.id)}
/>
))}
{isOpenComparison && (
)}
setSnackbar(prev => ({...prev, open: false}))}
>
setSnackbar(prev => ({...prev, open: false}))}
>
{snackbar.message}
>
)
}
VersionTimeline.propTypes = {
data: PropTypes.array.isRequired,
accessToken: PropTypes.string.isRequired,
userId: PropTypes.string.isRequired,
setError: PropTypes.func.isRequired,
setIsErrorAlertOpen: PropTypes.func.isRequired,
onVoteSuccess: PropTypes.func
}
VersionItem.propTypes = {
version: PropTypes.object.isRequired,
index: PropTypes.number.isRequired,
accessToken: PropTypes.string.isRequired,
userId: PropTypes.string.isRequired,
countdownRef: PropTypes.object.isRequired,
setError: PropTypes.func.isRequired,
setIsErrorAlertOpen: PropTypes.func.isRequired,
setIsOpenComparison: PropTypes.func.isRequired,
setVersionCompare: PropTypes.func.isRequired,
onVoteResult: PropTypes.func.isRequired
}