import { Add, Check, FolderOpen, Settings } from '@mui/icons-material'
import {
Avatar,
Box,
Button,
Divider,
ListItemContent,
ListItemDecorator,
Menu,
MenuItem,
Typography,
} from '@mui/joy'
import { useEffect, useRef, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import KeyboardShortcutHint from '../../components/common/KeyboardShortcutHint'
import LABEL_COLORS, {
getTextColorFromBackgroundColor,
} from '../../utils/Colors'
import { getIconComponent } from '../../utils/ProjectIcons'
import ProjectModal from '../Modals/Inputs/ProjectModal'
import { useProjects } from '../Projects/ProjectQueries'
const ProjectSelector = ({
selectedProject = 'Default Project',
onProjectSelect,
showKeyboardShortcuts = false,
}) => {
const { data: projects = [], isLoading } = useProjects()
const navigate = useNavigate()
const [anchorEl, setAnchorEl] = useState(null)
const [selectedIndex, setSelectedIndex] = useState(0)
const [isKeyboardNavigating, setIsKeyboardNavigating] = useState(false)
const [isProjectModalOpen, setIsProjectModalOpen] = useState(false)
const menuRef = useRef(null)
const buttonRef = useRef(null)
const defaultProjects = projects
// Check if selected project still exists, if not fallback to default
const selectedProjectExists = defaultProjects.some(
p => p.name === selectedProject,
)
const effectiveSelectedProject = selectedProjectExists
? selectedProject
: 'Default Project'
// Notify parent if selected project was deleted
useEffect(() => {
if (!selectedProjectExists && selectedProject !== 'Default Project') {
const defaultProject = defaultProjects.find(
p => p.id === 'default' || p.name === 'Default Project',
)
if (defaultProject) {
onProjectSelect?.(defaultProject)
}
}
}, [selectedProjectExists, selectedProject, defaultProjects, onProjectSelect])
const handleMenuOpen = event => {
setAnchorEl(event.currentTarget)
setIsKeyboardNavigating(false)
}
const handleMenuClose = () => {
setAnchorEl(null)
}
const handleProjectSelect = project => {
onProjectSelect?.(project)
handleMenuClose()
}
const handleAddProjectClick = () => {
setIsProjectModalOpen(true)
handleMenuClose()
}
const handleProjectModalSave = project => {
handleProjectSelect(project)
}
const handleManageProjects = () => {
navigate('/projects')
handleMenuClose()
}
useEffect(() => {
const handleMenuOutsideClick = event => {
if (menuRef.current && !menuRef.current.contains(event.target)) {
handleMenuClose()
}
}
document.addEventListener('mousedown', handleMenuOutsideClick)
return () => {
document.removeEventListener('mousedown', handleMenuOutsideClick)
}
}, [])
// Keyboard shortcut handler
useEffect(() => {
const handleKeyDown = event => {
const isHoldingCmdOrCtrl = event.ctrlKey || event.metaKey
// Cmd/Ctrl + E to open project menu
if (isHoldingCmdOrCtrl && event.key === 'e') {
event.preventDefault()
if (!anchorEl) {
setAnchorEl(buttonRef.current)
setSelectedIndex(0)
setIsKeyboardNavigating(true)
} else {
handleMenuClose()
}
return
}
// Only handle navigation keys when menu is open
if (!anchorEl) return
switch (event.key) {
case 'ArrowDown':
event.preventDefault()
setIsKeyboardNavigating(true)
setSelectedIndex(prev =>
prev < defaultProjects.length + 2 ? prev + 1 : prev,
)
break
case 'ArrowUp':
event.preventDefault()
setIsKeyboardNavigating(true)
setSelectedIndex(prev => (prev > 0 ? prev - 1 : prev))
break
case 'Enter':
event.preventDefault()
if (selectedIndex === 0) {
// Hardcoded Default Project
handleProjectSelect({
id: 'default',
name: 'Default Project',
color: LABEL_COLORS[0].value,
icon: 'FolderOpen',
})
} else if (selectedIndex <= defaultProjects.length) {
// Projects from the array (offset by 1)
handleProjectSelect(defaultProjects[selectedIndex - 1])
} else if (selectedIndex === defaultProjects.length + 1) {
handleAddProjectClick()
} else {
handleManageProjects()
}
break
case 'Escape':
event.preventDefault()
handleMenuClose()
break
}
}
document.addEventListener('keydown', handleKeyDown)
return () => {
document.removeEventListener('keydown', handleKeyDown)
}
}, [anchorEl, selectedIndex, defaultProjects, isKeyboardNavigating])
// Reset selected index when menu opens
useEffect(() => {
if (anchorEl) {
setSelectedIndex(0)
}
}, [anchorEl])
// Find the currently selected project
const currentProject = defaultProjects.find(
p => p.name === effectiveSelectedProject,
)
return (
<>