"use client" import { useState, useEffect, useRef } from "react" import { ChevronDown, Trash2 } from "lucide-react" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, DropdownMenuSeparator } from "@/components/ui/dropdown-menu" import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@/components/ui/alert-dialog" import { Version } from "@/lib/types" export function VersionDropdown({ onVersionSelect, currentVersion, onClearAll }: { onVersionSelect: (version: Version) => void, currentVersion?: string, onClearAll?: () => void }) { const [versions, setVersions] = useState([]); const [currentVersionId, setCurrentVersionId] = useState(null); const [showClearConfirm, setShowClearConfirm] = useState(false); const [userSelected, setUserSelected] = useState(false); const [isOpen, setIsOpen] = useState(false); const dropdownRef = useRef(null); // Update current version ID when prop changes useEffect(() => { if (currentVersion) { setCurrentVersionId(currentVersion); setUserSelected(true); } }, [currentVersion]); // Load versions from localStorage const loadVersions = () => { const storedVersions = localStorage.getItem('novita-versions'); if (storedVersions) { const parsedVersions = JSON.parse(storedVersions) as Version[]; // Sort versions by creation time, newest first const sortedVersions = parsedVersions.sort((a, b) => b.createdAt - a.createdAt); setVersions(sortedVersions); // Only set the current version to the newest one if there's no current version // We don't want to override a user selection if (!currentVersionId && sortedVersions.length > 0 && !userSelected) { setCurrentVersionId(sortedVersions[0].id); } } else { // Initialize with empty version list setVersions([]); } }; // Load versions from localStorage on mount and when localStorage changes useEffect(() => { loadVersions(); // Add event listener for storage changes const handleStorageChange = (e: StorageEvent) => { if (e.key === 'novita-versions') { loadVersions(); } }; window.addEventListener('storage', handleStorageChange); // Also check for updates periodically since the storage event // may not fire if the change is made in the same window const interval = setInterval(loadVersions, 1000); return () => { window.removeEventListener('storage', handleStorageChange); clearInterval(interval); }; }, [currentVersionId, userSelected]); // Handle click outside to close dropdown useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) { setIsOpen(false); } } if (isOpen) { document.addEventListener('mousedown', handleClickOutside); } return () => { document.removeEventListener('mousedown', handleClickOutside); } }, [isOpen]); // Handle version selection const handleVersionSelect = (version: Version) => { setCurrentVersionId(version.id); setUserSelected(true); setIsOpen(false); onVersionSelect(version); }; // Clear all versions const clearAllVersions = () => { setVersions([]); setCurrentVersionId(null); setUserSelected(false); localStorage.setItem('novita-versions', JSON.stringify([])); setShowClearConfirm(false); // Call the onClearAll callback if provided if (onClearAll) { onClearAll(); } }; // Get version name based on index const getVersionName = (index: number) => { return `v${versions.length - 1 - index}`; }; // Find the currently selected version's index const getCurrentVersionIndex = () => { if (!currentVersionId) return 0; const index = versions.findIndex(v => v.id === currentVersionId); return index !== -1 ? index : 0; }; if (versions.length === 0) { return null; } return ( <>
current version
setIsOpen(!isOpen)} className={` cursor-pointer flex items-center justify-between gap-2 text-white/90 hover:text-white px-3 py-1.5 rounded-md border border-novita-gray/30 hover:border-novita-gray/60 bg-novita-gray/5 hover:bg-novita-gray/20 transition-all duration-200 ease-in-out ${isOpen ? 'border-novita-gray/60 bg-novita-gray/20' : ''} `} > {versions.length > 0 ? getVersionName(getCurrentVersionIndex()) : "v0"}
{isOpen && (
{versions.map((version, index) => (
handleVersionSelect(version)} className={` px-4 py-2 text-xs cursor-pointer hover:bg-novita-gray/20 ${currentVersionId === version.id ? 'text-white bg-novita-gray/40' : 'text-white/70'} `} > {getVersionName(index)} {index === 0 ? "(Newest)" : ""}
))} {versions.length > 0 && ( <>
setShowClearConfirm(true)} > Clear All
)}
)}
Clear All Versions This will delete all saved versions. This action cannot be undone. Cancel Confirm ) }