Files
konstitisyon.nu/components/versions/vote-buttons.js
T

137 lines
3.9 KiB
JavaScript
Raw Normal View History

import {useState, useEffect} from 'react'
import PropTypes from 'prop-types'
import Box from '@mui/material/Box'
import IconButton from '@mui/material/IconButton'
import Typography from '@mui/material/Typography'
import ThumbUpIcon from '@mui/icons-material/ThumbUp'
import ThumbDownIcon from '@mui/icons-material/ThumbDown'
import {useSession} from 'next-auth/react'
import {handleVote, getUserVote} from '@/lib/directus.js'
export default function VoteButtons({versionId, isDisabled = false, hasCountsVisible = false, voteCounts = null, onVoteResult = null}) {
const {data: session} = useSession()
const [currentVote, setCurrentVote] = useState(null)
useEffect(() => {
const fetchVote = async () => {
if (session?.user && versionId) {
try {
const vote = await getUserVote({
accessToken: session.user.accessToken,
userId: session.user.userId,
versionId
})
setCurrentVote(vote)
} catch (error) {
console.error('Error fetching vote:', error)
}
}
}
fetchVote()
}, [session, versionId])
const handleVoteClick = async voteValue => {
if (isDisabled) {
return
}
try {
const newVoteValue = await handleVote({
accessToken: session.user.accessToken,
userId: session.user.userId,
versionId,
voteValue
})
setCurrentVote(newVoteValue)
if (onVoteResult) {
onVoteResult({
success: true,
message: newVoteValue === null ? 'Vote annulé' : 'Vote enregistré avec succès'
})
}
} catch (error) {
if (onVoteResult) {
onVoteResult({
success: false,
message: error.message || 'Erreur lors du vote'
})
}
}
}
if (!session?.user) {
return null
}
return (
<Box sx={{display: 'flex', alignItems: 'center', gap: 1}}>
<Box sx={{display: 'flex', alignItems: 'center'}}>
<IconButton
size='small'
aria-label='vote positif'
disabled={isDisabled}
sx={{
color: currentVote === 1 ? '#2E7D32' : '#666666',
backgroundColor: currentVote === 1 ? 'rgba(46, 125, 50, 0.1)' : 'transparent',
'&:hover': {
backgroundColor: 'rgba(46, 125, 50, 0.2)',
color: '#2E7D32'
},
'&:disabled': {
color: '#CCCCCC'
}
}}
onClick={() => handleVoteClick(1)}
>
<ThumbUpIcon />
</IconButton>
{hasCountsVisible && voteCounts && (
<Typography variant='caption' sx={{color: '#333333', ml: 0.5, fontWeight: 'bold'}}>
{voteCounts.positive || 0}
</Typography>
)}
</Box>
<Box sx={{display: 'flex', alignItems: 'center'}}>
<IconButton
size='small'
aria-label='vote négatif'
disabled={isDisabled}
sx={{
color: currentVote === -1 ? '#D32F2F' : '#666666',
backgroundColor: currentVote === -1 ? 'rgba(211, 47, 47, 0.1)' : 'transparent',
'&:hover': {
backgroundColor: 'rgba(211, 47, 47, 0.2)',
color: '#D32F2F'
},
'&:disabled': {
color: '#CCCCCC'
}
}}
onClick={() => handleVoteClick(-1)}
>
<ThumbDownIcon />
</IconButton>
{hasCountsVisible && voteCounts && (
<Typography variant='caption' sx={{color: '#333333', ml: 0.5, fontWeight: 'bold'}}>
{voteCounts.negative || 0}
</Typography>
)}
</Box>
</Box>
)
}
VoteButtons.propTypes = {
versionId: PropTypes.string.isRequired,
isDisabled: PropTypes.bool,
hasCountsVisible: PropTypes.bool,
voteCounts: PropTypes.shape({
positive: PropTypes.number,
negative: PropTypes.number
}),
onVoteResult: PropTypes.func
}