import React, { useState, useRef, useEffect } from 'react'; import { ChevronDownIcon, ClipboardDocumentListIcon, PlayIcon, CheckCircleIcon, ClockIcon, XCircleIcon, EllipsisHorizontalCircleIcon, } from '@heroicons/react/24/outline'; import { ProjectStatus } from '../../entities/Project'; import { useTranslation } from 'react-i18next'; interface ProjectStateDropdownProps { value: ProjectStatus; onChange: (value: ProjectStatus) => void; } const ProjectStateDropdown: React.FC = ({ value, onChange, }) => { const { t } = useTranslation(); const states = [ { value: 'not_started' as ProjectStatus, label: t('projectStatus.not_started', 'Not Started'), description: t( 'projectStatus.not_started_desc', 'captured but not started yet' ), icon: ( ), }, { value: 'planned' as ProjectStatus, label: t('projectStatus.planned', 'Planned'), description: t( 'projectStatus.planned_desc', 'scoped and ready to start' ), icon: ( ), }, { value: 'in_progress' as ProjectStatus, label: t('projectStatus.in_progress', 'In Progress'), description: t( 'projectStatus.in_progress_desc', 'active work happening' ), icon: , }, { value: 'waiting' as ProjectStatus, label: t('projectStatus.waiting', 'Waiting'), description: t( 'projectStatus.waiting_desc', 'waiting on external input' ), icon: , }, { value: 'done' as ProjectStatus, label: t('projectStatus.done', 'Completed'), description: t('projectStatus.done_desc', 'finished and done'), icon: , }, { value: 'cancelled' as ProjectStatus, label: t('projectStatus.cancelled', 'Cancelled'), description: t( 'projectStatus.cancelled_desc', 'will not be completed' ), 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 = (status: ProjectStatus) => { onChange(status); 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;