import { Archive, CopyAll, Delete, Edit, ManageSearch, MoreTime, MoreVert, Nfc, NoteAdd, RecordVoiceOver, SwitchAccessShortcut, Unarchive, Update, ViewCarousel, } from '@mui/icons-material' import { Divider, IconButton, Menu, MenuItem } from '@mui/joy' import React, { useEffect } from 'react' import { useNavigate } from 'react-router-dom' import { useError } from '../../service/ErrorProvider' import { ArchiveChore, DeleteChore, SkipChore, UnArchiveChore, } from '../../utils/Fetcher' const ChoreActionMenu = ({ chore, onChoreUpdate, onChoreRemove, onCompleteWithNote, onCompleteWithPastDate, onChangeAssignee, onChangeDueDate, onWriteNFC, onDelete, sx = {}, variant = 'soft', }) => { const [anchorEl, setAnchorEl] = React.useState(null) const menuRef = React.useRef(null) const navigate = useNavigate() const { showError } = useError() useEffect(() => { const handleMenuOutsideClick = event => { if ( anchorEl && !anchorEl.contains(event.target) && !menuRef.current.contains(event.target) ) { handleMenuClose() } } document.addEventListener('mousedown', handleMenuOutsideClick) return () => { document.removeEventListener('mousedown', handleMenuOutsideClick) } }, [anchorEl]) const handleMenuOpen = event => { event.stopPropagation() setAnchorEl(event.currentTarget) } const handleMenuClose = () => { setAnchorEl(null) } const handleEdit = () => { navigate(`/chores/${chore.id}/edit`) handleMenuClose() } const handleClone = () => { navigate(`/chores/${chore.id}/edit?clone=true`) handleMenuClose() } const handleView = () => { navigate(`/chores/${chore.id}`) handleMenuClose() } const handleDelete = () => { if (onDelete) { onDelete() } else { // Default delete behavior DeleteChore(chore.id).then(response => { if (response.ok) { onChoreRemove?.(chore) } }) } handleMenuClose() } const handleArchive = () => { if (chore.isActive) { ArchiveChore(chore.id).then(response => { if (response.ok) { response.json().then(() => { const newChore = { ...chore, isActive: false } onChoreUpdate?.(newChore, 'archive') }) } }) } else { UnArchiveChore(chore.id).then(response => { if (response.ok) { response.json().then(() => { const newChore = { ...chore, isActive: true } onChoreUpdate?.(newChore, 'unarchive') }) } }) } handleMenuClose() } const handleSkip = () => { SkipChore(chore.id) .then(response => { if (response.ok) { response.json().then(data => { const newChore = data.res onChoreUpdate?.(newChore, 'skipped') handleMenuClose() }) } }) .catch(error => { if (error?.queued) { showError({ title: 'Failed to update', message: 'Request will be processed when you are online', }) } else { showError({ title: 'Failed to update', message: error, }) } }) } const handleHistory = () => { navigate(`/chores/${chore.id}/history`) handleMenuClose() } return ( <> { e.stopPropagation() onCompleteWithNote?.() handleMenuClose() }} > Complete with note { e.stopPropagation() onCompleteWithPastDate?.() handleMenuClose() }} > Complete in past { e.stopPropagation() handleSkip() }} > Skip to next due date { e.stopPropagation() onChangeAssignee?.() handleMenuClose() }} > Delegate to someone else { e.stopPropagation() handleHistory() }} > History { e.stopPropagation() onChangeDueDate?.() handleMenuClose() }} > Change due date { e.stopPropagation() onWriteNFC?.() handleMenuClose() }} > Write to NFC { e.stopPropagation() handleEdit() }} > Edit { e.stopPropagation() handleClone() }} > Clone { e.stopPropagation() handleView() }} > View { e.stopPropagation() handleArchive() }} color='neutral' > {chore.isActive ? : } {chore.isActive ? 'Archive' : 'Unarchive'} { e.stopPropagation() handleDelete() }} color='danger' > Delete ) } export default ChoreActionMenu