import React, { useState, useRef, useEffect } from 'react'; import { ChevronDownIcon, LightBulbIcon, ClipboardDocumentListIcon, PlayIcon, ExclamationTriangleIcon, CheckCircleIcon, } from '@heroicons/react/24/outline'; import { ProjectState } from '../../entities/Project'; import { useTranslation } from 'react-i18next'; interface ProjectStateDropdownProps { value: ProjectState; onChange: (value: ProjectState) => void; } const ProjectStateDropdown: React.FC = ({ value, onChange, }) => { const { t } = useTranslation(); const states = [ { value: 'idea' as ProjectState, label: t('projects.states.idea', 'Idea'), description: t( 'projects.states.idea_desc', 'captured but not planned yet' ), icon: , }, { value: 'planned' as ProjectState, label: t('projects.states.planned', 'Planned'), description: t( 'projects.states.planned_desc', 'scoped and ready to start' ), icon: ( ), }, { value: 'in_progress' as ProjectState, label: t('projects.states.in_progress', 'In Progress'), description: t( 'projects.states.in_progress_desc', 'active work happening' ), icon: , }, { value: 'blocked' as ProjectState, label: t('projects.states.blocked', 'Blocked'), description: t( 'projects.states.blocked_desc', 'temporarily paused or stuck' ), icon: , }, { value: 'completed' as ProjectState, label: t('projects.states.completed', 'Completed'), description: t( 'projects.states.completed_desc', 'finished and done' ), icon: , }, ]; const [isOpen, setIsOpen] = useState(false); const dropdownRef = useRef(null); const handleToggle = () => { setIsOpen(!isOpen); // Scroll dropdown into view when opening to ensure options are visible if (!isOpen && dropdownRef.current) { setTimeout(() => { // Find the dropdown options container const dropdownOptions = dropdownRef.current?.querySelector('.absolute.z-10'); if (dropdownOptions) { dropdownOptions.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest', }); } else { // Fallback to scrolling the dropdown container itself dropdownRef.current?.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest', }); } }, 150); // Increased timeout to ensure dropdown is rendered } }; const handleClickOutside = (event: MouseEvent) => { if ( dropdownRef.current && !dropdownRef.current.contains(event.target as Node) ) { setIsOpen(false); } }; const handleSelect = (state: ProjectState) => { onChange(state); setIsOpen(false); }; useEffect(() => { if (isOpen) { document.addEventListener('mousedown', handleClickOutside); // Ensure dropdown is visible after opening setTimeout(() => { const dropdownOptions = dropdownRef.current?.querySelector('.absolute.z-10'); if (dropdownOptions) { // Try to scroll the parent modal container to show the dropdown const modalScrollContainer = document.querySelector( '.absolute.inset-0.overflow-y-auto' ) || document.querySelector('[style*="overflow-y"]') || document.querySelector('.overflow-y-auto'); if (modalScrollContainer) { const rect = dropdownOptions.getBoundingClientRect(); const containerRect = modalScrollContainer.getBoundingClientRect(); // Check if dropdown is below visible area if (rect.bottom > containerRect.bottom) { modalScrollContainer.scrollTo({ top: modalScrollContainer.scrollTop + (rect.bottom - containerRect.bottom) + 20, behavior: 'smooth', }); } } else { // Fallback to scrollIntoView dropdownOptions.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest', }); } } }, 200); } else { document.removeEventListener('mousedown', handleClickOutside); } return () => { document.removeEventListener('mousedown', handleClickOutside); }; }, [isOpen]); const selectedState = states.find((s) => s.value === value); return (
{isOpen && (
{states.map((state) => ( ))}
)}
); }; export default ProjectStateDropdown;