feat: Add turtle management features including rename, configuration, and GPS locate

This commit is contained in:
MayaTheShy
2026-02-20 02:35:17 -05:00
parent d8f3d5d13c
commit a0eaeb6712

View File

@@ -79,6 +79,21 @@ function TurtleCard({ turtle, isSelected, onSelect }) {
function TurtleDetails({ turtle }) {
const sendCommand = useTurtleStore((state) => state.sendCommand);
const setTurtleState = useTurtleStore((state) => state.setTurtleState);
const renameTurtle = useTurtleStore((state) => state.renameTurtle);
const equipLeft = useTurtleStore((state) => state.equipLeft);
const equipRight = useTurtleStore((state) => state.equipRight);
const sortInventory = useTurtleStore((state) => state.sortInventory);
const selectSlot = useTurtleStore((state) => state.selectSlot);
const dropItems = useTurtleStore((state) => state.dropItems);
const suckItems = useTurtleStore((state) => state.suckItems);
const connectToInventory = useTurtleStore((state) => state.connectToInventory);
const updateTurtleConfig = useTurtleStore((state) => state.updateTurtleConfig);
const exploreTurtle = useTurtleStore((state) => state.exploreTurtle);
const gpsLocateTurtle = useTurtleStore((state) => state.gpsLocateTurtle);
const [renameValue, setRenameValue] = useState('');
const [showConfig, setShowConfig] = useState(false);
const [configValues, setConfigValues] = useState({ maxDistance: 200, autoRefuel: true });
if (!turtle) {
return (
@@ -96,11 +111,66 @@ function TurtleDetails({ turtle }) {
setTurtleState(turtle.turtleID, stateName, data);
};
const handleRename = async () => {
if (renameValue.trim()) {
await renameTurtle(turtle.turtleID, renameValue.trim());
setRenameValue('');
}
};
const handleSlotClick = async (slotIndex) => {
await selectSlot(turtle.turtleID, slotIndex + 1);
};
const handleConfigSave = async () => {
await updateTurtleConfig(turtle.turtleID, configValues);
setShowConfig(false);
};
const activeState = turtle.state || turtle.mode || 'idle';
const displayName = turtle.label || `Turtle ${turtle.turtleID}`;
return (
<div className="turtle-details">
<h2>Turtle {turtle.turtleID} Control</h2>
<h2>{displayName} <span style={{color: '#6b7280', fontSize: '0.8em'}}>#{turtle.turtleID}</span></h2>
{/* Rename + Config bar */}
<div className="detail-section" style={{ display: 'flex', gap: '8px', alignItems: 'center', flexWrap: 'wrap' }}>
<input
type="text"
value={renameValue}
onChange={(e) => setRenameValue(e.target.value)}
onKeyDown={(e) => e.key === 'Enter' && handleRename()}
placeholder="Rename turtle..."
className="rename-input"
style={{ flex: 1, minWidth: '120px', padding: '4px 8px', borderRadius: '4px', border: '1px solid #4b5563', background: '#1f2937', color: '#fff' }}
/>
<button onClick={handleRename} className="command-btn" style={{ padding: '4px 12px' }}>📝 Rename</button>
<button onClick={() => setShowConfig(!showConfig)} className="command-btn" style={{ padding: '4px 12px' }}> Config</button>
<button onClick={() => gpsLocateTurtle(turtle.turtleID)} className="command-btn" style={{ padding: '4px 12px' }}>📡 GPS</button>
<button onClick={() => exploreTurtle(turtle.turtleID)} className="command-btn" style={{ padding: '4px 12px' }}>🔎 Inspect</button>
</div>
{/* Config Modal */}
{showConfig && (
<div className="detail-section" style={{ background: '#1e293b', padding: '12px', borderRadius: '8px', border: '1px solid #334155' }}>
<h3> Configuration</h3>
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px', marginTop: '8px' }}>
<label style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span>Max Distance:</span>
<input type="number" value={configValues.maxDistance} onChange={(e) => setConfigValues({...configValues, maxDistance: parseInt(e.target.value)})} style={{ width: '80px', padding: '2px 6px', borderRadius: '4px', border: '1px solid #4b5563', background: '#0f172a', color: '#fff' }} />
</label>
<label style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span>Auto Refuel:</span>
<input type="checkbox" checked={configValues.autoRefuel} onChange={(e) => setConfigValues({...configValues, autoRefuel: e.target.checked})} />
</label>
<div style={{ display: 'flex', gap: '8px', justifyContent: 'flex-end' }}>
<button onClick={() => setShowConfig(false)} className="command-btn" style={{ padding: '4px 12px' }}>Cancel</button>
<button onClick={handleConfigSave} className="command-btn explore" style={{ padding: '4px 12px' }}>💾 Save</button>
</div>
</div>
</div>
)}
<div className="detail-section">
<h3>Status</h3>