Initial commit: Refactor AgvAutoRunControls
This commit is contained in:
119
components/AgvManualControls.tsx
Normal file
119
components/AgvManualControls.tsx
Normal file
@@ -0,0 +1,119 @@
|
||||
|
||||
import React from 'react';
|
||||
import { ArrowUp, ArrowDown, RotateCcw, RotateCw, StopCircle, Disc } from 'lucide-react';
|
||||
import { AgvState, AgvMotionState, AgvRunConfig } from '../types';
|
||||
|
||||
interface AgvManualControlsProps {
|
||||
agvState: AgvState;
|
||||
setMotion: (state: AgvMotionState) => void;
|
||||
updateRunConfig: (key: keyof AgvRunConfig, value: any) => void;
|
||||
onTurn180: (direction: 'LEFT' | 'RIGHT') => void;
|
||||
handleMarkStop: () => void;
|
||||
isRunning: boolean;
|
||||
isError: boolean;
|
||||
}
|
||||
|
||||
const AgvManualControls: React.FC<AgvManualControlsProps> = ({
|
||||
agvState,
|
||||
setMotion,
|
||||
updateRunConfig,
|
||||
onTurn180,
|
||||
handleMarkStop,
|
||||
isRunning,
|
||||
isError,
|
||||
}) => {
|
||||
const setManualMotion = (motion: AgvMotionState, direction?: 'FWD' | 'BWD') => {
|
||||
setMotion(motion);
|
||||
if (direction) {
|
||||
updateRunConfig('direction', direction);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`${isError ? 'opacity-50 pointer-events-none' : ''}`}>
|
||||
<div className="flex justify-between items-center mb-2 px-1">
|
||||
<h3 className="text-xs font-bold text-gray-400 uppercase tracking-wider">Manual Operation</h3>
|
||||
</div>
|
||||
|
||||
<div className="bg-gray-800 rounded-lg p-3 border border-gray-700 shadow-inner">
|
||||
<div className="grid grid-cols-3 gap-2 mb-3">
|
||||
<div />
|
||||
<button
|
||||
disabled={isRunning}
|
||||
onMouseDown={() => setManualMotion(AgvMotionState.FORWARD, 'FWD')}
|
||||
onMouseUp={() => setManualMotion(AgvMotionState.IDLE)}
|
||||
className="h-10 bg-gray-700 hover:bg-gray-600 rounded flex items-center justify-center active:bg-blue-600 disabled:opacity-30 transition-colors shadow"
|
||||
>
|
||||
<ArrowUp size={24} />
|
||||
</button>
|
||||
<div />
|
||||
|
||||
<button
|
||||
disabled={isRunning}
|
||||
onMouseDown={() => setManualMotion(AgvMotionState.TURN_LEFT)}
|
||||
onMouseUp={() => setManualMotion(AgvMotionState.IDLE)}
|
||||
className="h-10 bg-gray-700 hover:bg-gray-600 rounded flex items-center justify-center active:bg-blue-600 disabled:opacity-30 transition-colors shadow"
|
||||
>
|
||||
<RotateCcw size={20} />
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setManualMotion(AgvMotionState.IDLE)}
|
||||
className="h-10 bg-red-800 hover:bg-red-700 rounded flex items-center justify-center text-white shadow"
|
||||
>
|
||||
<StopCircle size={24} />
|
||||
</button>
|
||||
<button
|
||||
disabled={isRunning}
|
||||
onMouseDown={() => setManualMotion(AgvMotionState.TURN_RIGHT)}
|
||||
onMouseUp={() => setManualMotion(AgvMotionState.IDLE)}
|
||||
className="h-10 bg-gray-700 hover:bg-gray-600 rounded flex items-center justify-center active:bg-blue-600 disabled:opacity-30 transition-colors shadow"
|
||||
>
|
||||
<RotateCw size={20} />
|
||||
</button>
|
||||
|
||||
<div />
|
||||
<button
|
||||
disabled={isRunning}
|
||||
onMouseDown={() => setManualMotion(AgvMotionState.BACKWARD, 'BWD')}
|
||||
onMouseUp={() => setManualMotion(AgvMotionState.IDLE)}
|
||||
className="h-10 bg-gray-700 hover:bg-gray-600 rounded flex items-center justify-center active:bg-blue-600 disabled:opacity-30 transition-colors shadow"
|
||||
>
|
||||
<ArrowDown size={24} />
|
||||
</button>
|
||||
<div />
|
||||
</div>
|
||||
|
||||
{/* Extra Actions */}
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<button
|
||||
disabled={isRunning}
|
||||
onClick={() => onTurn180('LEFT')}
|
||||
className="text-xs py-1.5 bg-gray-700 rounded hover:bg-gray-600 flex items-center justify-center gap-1 disabled:opacity-30 shadow-sm"
|
||||
>
|
||||
<RotateCcw size={12} /> L-Turn 180
|
||||
</button>
|
||||
<button
|
||||
disabled={isRunning}
|
||||
onClick={() => onTurn180('RIGHT')}
|
||||
className="text-xs py-1.5 bg-gray-700 rounded hover:bg-gray-600 flex items-center justify-center gap-1 disabled:opacity-30 shadow-sm"
|
||||
>
|
||||
<RotateCw size={12} /> R-Turn 180
|
||||
</button>
|
||||
<button
|
||||
disabled={!isRunning || agvState.motionState === AgvMotionState.MARK_STOPPING}
|
||||
onClick={handleMarkStop}
|
||||
className={`col-span-2 text-xs py-1.5 border rounded flex items-center justify-center gap-1 shadow-sm transition-colors disabled:opacity-30 ${
|
||||
agvState.motionState === AgvMotionState.MARK_STOPPING
|
||||
? 'bg-yellow-600 text-black border-yellow-500 font-bold'
|
||||
: 'bg-yellow-900/50 text-yellow-200 border-yellow-800/50 hover:bg-yellow-900/70'
|
||||
}`}
|
||||
>
|
||||
<Disc size={12} /> {agvState.motionState === AgvMotionState.MARK_STOPPING ? 'Stopping at Mark...' : 'Drive to Next Mark'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AgvManualControls;
|
||||
Reference in New Issue
Block a user