import {
Archive,
ArrowBack,
Cancel,
CopyAll,
Delete,
DriveFileMove,
Edit,
ManageSearch,
MoreTime,
MoreVert,
NextWeek,
Nfc,
NoteAdd,
Notifications,
RecordVoiceOver,
SwitchAccessShortcut,
Today,
Unarchive,
Update,
ViewCarousel,
WbSunny,
Weekend,
} from '@mui/icons-material'
import {
Avatar,
Divider,
IconButton,
ListItemContent,
ListItemDecorator,
Menu,
MenuItem,
Tooltip,
Typography,
} from '@mui/joy'
import React, { useEffect, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import LABEL_COLORS, {
getTextColorFromBackgroundColor,
} from '../../utils/Colors'
import { isOfficialDonetickInstanceSync } from '../../utils/FeatureToggle'
import { getIconComponent } from '../../utils/ProjectIcons'
import { useProjects } from '../Projects/ProjectQueries'
const ChoreActionMenu = ({
chore,
onAction,
onCompleteWithNote,
onCompleteWithPastDate,
onChangeAssignee,
onChangeDueDate,
onWriteNFC,
onNudge,
onDelete,
onOpen,
onMouseEnter,
onMouseLeave,
sx = {},
variant = 'soft',
}) => {
const [anchorEl, setAnchorEl] = React.useState(null)
const [isOfficialInstance, setIsOfficialInstance] = useState(false)
const [showProjectPicker, setShowProjectPicker] = useState(false)
const menuRef = React.useRef(null)
const navigate = useNavigate()
const { data: projects = [] } = useProjects()
useEffect(() => {
try {
setIsOfficialInstance(isOfficialDonetickInstanceSync())
} catch (error) {
console.warn('Error checking instance type:', error)
setIsOfficialInstance(false)
}
}, [])
useEffect(() => {
const handleMenuOutsideClick = event => {
if (
anchorEl &&
!anchorEl.contains(event.target) &&
!menuRef.current.contains(event.target)
) {
handleMenuClose()
}
}
document.addEventListener('mousedown', handleMenuOutsideClick)
if (anchorEl && onOpen) {
onOpen()
}
return () => {
document.removeEventListener('mousedown', handleMenuOutsideClick)
}
}, [anchorEl, onOpen])
const handleMenuOpen = event => {
event.stopPropagation()
setAnchorEl(event.currentTarget)
}
const handleMenuClose = () => {
setAnchorEl(null)
setShowProjectPicker(false)
}
const handleMoveToProject = project => {
onAction?.('moveToProject', chore, { project })
handleMenuClose()
}
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 {
onAction?.('delete', chore)
}
handleMenuClose()
}
const handleArchive = () => {
if (chore.isActive) {
onAction?.('archive', chore)
} else {
onAction?.('unarchive', chore)
}
handleMenuClose()
}
const handleSkip = () => {
onAction?.('skip', chore)
handleMenuClose()
}
const handleHistory = () => {
navigate(`/chores/${chore.id}/history`)
handleMenuClose()
}
const getQuickScheduleDate = option => {
const now = new Date()
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate())
switch (option) {
case 'today': {
const nowHour = now.getHours()
const scheduled = new Date(today)
if (nowHour < 9) {
scheduled.setHours(9, 0, 0, 0)
} else if (nowHour < 12) {
scheduled.setHours(12, 0, 0, 0)
} else if (nowHour < 17) {
scheduled.setHours(17, 0, 0, 0)
} else {
scheduled.setHours(
now.getHours(),
now.getMinutes(),
now.getSeconds(),
now.getMilliseconds(),
)
}
return scheduled
}
case 'tomorrow-morning': {
const tomorrowMorning = new Date(today)
tomorrowMorning.setDate(today.getDate() + 1)
tomorrowMorning.setHours(9, 0, 0, 0)
return tomorrowMorning
}
case 'tomorrow': {
const tomorrow = new Date(today)
tomorrow.setDate(today.getDate() + 1)
tomorrow.setHours(12, 0, 0, 0)
return tomorrow
}
case 'tomorrow-afternoon': {
const tomorrowAfternoon = new Date(today)
tomorrowAfternoon.setDate(today.getDate() + 1)
tomorrowAfternoon.setHours(14, 0, 0, 0)
return tomorrowAfternoon
}
case 'weekend': {
const weekend = new Date(today)
const daysUntilSaturday = (6 - today.getDay() + 7) % 7 || 7
weekend.setDate(today.getDate() + daysUntilSaturday)
return weekend
}
case 'next-week': {
const nextWeek = new Date(today)
const daysUntilMonday = (1 - today.getDay() + 7) % 7 || 7
nextWeek.setDate(today.getDate() + daysUntilMonday)
return nextWeek
}
default:
return today
}
}
const handleQuickSchedule = option => {
const date = option === 'remove' ? null : getQuickScheduleDate(option)
onAction?.('changeDueDate', chore, { date })
handleMenuClose()
}
const renderProjectAvatar = (color, icon) => {
const bg = color || LABEL_COLORS[0].value
const IconComponent = getIconComponent(icon || 'FolderOpen')
return (