import { Check, ChevronDown, Edit2, X } from "lucide-react"; import React, { useCallback, useEffect, useMemo, useRef, useState, } from "react"; const InlineGroupEdit = ({ value, onSave, onCancel, options = [], className = "", disabled = false, placeholder = "Select group...", }) => { const [isEditing, setIsEditing] = useState(false); const [selectedValue, setSelectedValue] = useState(value); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(""); const [isOpen, setIsOpen] = useState(false); const [dropdownPosition, setDropdownPosition] = useState({ top: 0, left: 0, width: 0, }); const dropdownRef = useRef(null); const buttonRef = useRef(null); useEffect(() => { if (isEditing && dropdownRef.current) { dropdownRef.current.focus(); } }, [isEditing]); useEffect(() => { setSelectedValue(value); // Force re-render when value changes if (!isEditing) { setIsOpen(false); } }, [value, isEditing]); // Calculate dropdown position const calculateDropdownPosition = useCallback(() => { if (buttonRef.current) { const rect = buttonRef.current.getBoundingClientRect(); setDropdownPosition({ top: rect.bottom + window.scrollY + 4, left: rect.left + window.scrollX, width: rect.width, }); } }, []); // Close dropdown when clicking outside useEffect(() => { const handleClickOutside = (event) => { if (dropdownRef.current && !dropdownRef.current.contains(event.target)) { setIsOpen(false); } }; if (isOpen) { calculateDropdownPosition(); document.addEventListener("mousedown", handleClickOutside); window.addEventListener("resize", calculateDropdownPosition); window.addEventListener("scroll", calculateDropdownPosition); return () => { document.removeEventListener("mousedown", handleClickOutside); window.removeEventListener("resize", calculateDropdownPosition); window.removeEventListener("scroll", calculateDropdownPosition); }; } }, [isOpen, calculateDropdownPosition]); const handleEdit = () => { if (disabled) return; setIsEditing(true); setSelectedValue(value); setError(""); // Automatically open dropdown when editing starts setTimeout(() => { setIsOpen(true); }, 0); }; const handleCancel = () => { setIsEditing(false); setSelectedValue(value); setError(""); setIsOpen(false); if (onCancel) onCancel(); }; const handleSave = async () => { if (disabled || isLoading) return; // Check if value actually changed if (selectedValue === value) { setIsEditing(false); setIsOpen(false); return; } setIsLoading(true); setError(""); try { await onSave(selectedValue); // Update the local value to match the saved value setSelectedValue(selectedValue); setIsEditing(false); setIsOpen(false); } catch (err) { setError(err.message || "Failed to save"); } finally { setIsLoading(false); } }; const handleKeyDown = (e) => { if (e.key === "Enter") { e.preventDefault(); handleSave(); } else if (e.key === "Escape") { e.preventDefault(); handleCancel(); } }; const displayValue = useMemo(() => { if (!value) { return "Ungrouped"; } const option = options.find((opt) => opt.id === value); return option ? option.name : "Unknown Group"; }, [value, options]); const displayColor = useMemo(() => { if (!value) return "bg-secondary-100 text-secondary-800"; const option = options.find((opt) => opt.id === value); return option ? `text-white` : "bg-secondary-100 text-secondary-800"; }, [value, options]); const selectedOption = useMemo(() => { return options.find((opt) => opt.id === value); }, [value, options]); if (isEditing) { return (