108 lines
3.4 KiB
TypeScript
108 lines
3.4 KiB
TypeScript
import { useState, useRef } from 'react';
|
|
import { System } from '@/lib/types';
|
|
|
|
interface SystemContextMenuProps {
|
|
x: number;
|
|
y: number;
|
|
system: System;
|
|
onRename: (newName: string) => void;
|
|
onDelete: (system: System) => void;
|
|
onClearConnections: (system: System) => void;
|
|
onSetDestination?: (systemName: string, viaMode: boolean) => void;
|
|
onClose: () => void;
|
|
}
|
|
|
|
export const SystemContextMenu = ({ x, y, system, onRename, onDelete, onClearConnections, onSetDestination, onClose }: SystemContextMenuProps) => {
|
|
if (!system) {
|
|
return null;
|
|
}
|
|
const [isRenaming, setIsRenaming] = useState(false);
|
|
const [newName, setNewName] = useState(system.solarSystemName);
|
|
const menuRef = useRef<HTMLDivElement>(null);
|
|
|
|
const handleRename = () => {
|
|
if (newName.trim() && newName !== system.solarSystemName) {
|
|
onRename(newName);
|
|
onClose();
|
|
}
|
|
setIsRenaming(false);
|
|
};
|
|
|
|
const handleSetDestinationClick = (e: React.MouseEvent) => {
|
|
const via = !!e.shiftKey;
|
|
if (typeof onSetDestination === 'function') {
|
|
onSetDestination(system.solarSystemName, via);
|
|
} else {
|
|
console.error('onSetDestination not provided');
|
|
}
|
|
onClose();
|
|
};
|
|
|
|
return (
|
|
<div
|
|
ref={menuRef}
|
|
className="fixed bg-slate-800 border border-slate-600 rounded-lg shadow-lg p-2 z-50"
|
|
style={{ left: x, top: y }}
|
|
onClick={(e) => e.stopPropagation()}
|
|
>
|
|
{isRenaming ? (
|
|
<div className="space-y-2">
|
|
<input
|
|
type="text"
|
|
value={newName}
|
|
onChange={(e) => setNewName(e.target.value)}
|
|
className="w-full px-2 py-1 bg-slate-700 border border-slate-600 rounded text-white"
|
|
autoFocus
|
|
onKeyDown={(e) => {
|
|
if (e.key === 'Enter') handleRename();
|
|
if (e.key === 'Escape') setIsRenaming(false);
|
|
}}
|
|
/>
|
|
<div className="flex space-x-2">
|
|
<button
|
|
onClick={handleRename}
|
|
className="px-2 py-1 bg-blue-600 hover:bg-blue-700 rounded text-white text-sm"
|
|
>
|
|
Save
|
|
</button>
|
|
<button
|
|
onClick={() => setIsRenaming(false)}
|
|
className="px-2 py-1 bg-slate-600 hover:bg-slate-700 rounded text-white text-sm"
|
|
>
|
|
Cancel
|
|
</button>
|
|
</div>
|
|
</div>
|
|
) : (
|
|
<div className="space-y-1">
|
|
<button
|
|
onClick={() => setIsRenaming(true)}
|
|
className="w-full px-3 py-1 text-left text-white hover:bg-slate-700 rounded text-sm"
|
|
>
|
|
Rename
|
|
</button>
|
|
<button
|
|
onClick={() => onClearConnections(system)}
|
|
className="w-full px-3 py-1 text-left text-white hover:bg-slate-700 rounded text-sm"
|
|
>
|
|
Clear Connections
|
|
</button>
|
|
<button
|
|
onClick={() => onDelete(system)}
|
|
className="w-full px-3 py-1 text-left text-red-400 hover:bg-slate-700 rounded text-sm"
|
|
>
|
|
Delete
|
|
</button>
|
|
<div className="h-px bg-slate-700 my-1" />
|
|
<button
|
|
onClick={handleSetDestinationClick}
|
|
className="w-full px-3 py-1 text-left text-emerald-400 hover:bg-slate-700 rounded text-sm"
|
|
title="Shift-click to enter via mode and append waypoints"
|
|
>
|
|
Set destination
|
|
</button>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|