feat: ajoute composant VoteButtons réutilisable
This commit is contained in:
@@ -0,0 +1,136 @@
|
|||||||
|
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: `Erreur lors du vote: ${error}`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user