SimulationControl.tsx 5,44 ko
Newer Older
/**
 * Simulation control buttons - Start, Stop, Reset, Clear Results.
 */
import { useSimulationStore } from '../../store/simulationStore';

export default function SimulationControl() {
  const {
    config,
    isRunning,
    isLoading,
    simulationResults,
    startSimulation,
    stopSimulation,
    clearResults,
    reset,
  } = useSimulationStore();

  const canStart = config !== null && !isRunning && !isLoading;
  const canStop = isRunning;
  const canClear = simulationResults !== null && !isRunning;

  return (
    <div className="space-y-4">
      <div className="border-t border-gray-200 pt-4">
        <h3 className="text-sm font-medium text-gray-700 mb-3">Contrôle de simulation</h3>

        {/* Status indicator */}
        <div className="mb-4">
          <div className="flex items-center space-x-2">
            <div
              className={`w-3 h-3 rounded-full ${
                isRunning
                  ? 'bg-yellow-400 animate-pulse'
                  : simulationResults
                  ? 'bg-green-400'
                  : 'bg-gray-300'
              }`}
            />
            <span className="text-sm text-gray-600">
              {isRunning
                ? 'Simulation en cours...'
                : simulationResults
                ? 'Simulation terminée'
                : 'Prêt à simuler'}
            </span>
          </div>
        </div>

        {/* Action buttons */}
        <div className="space-y-2">
          {/* Start button */}
          <button
            onClick={startSimulation}
            disabled={!canStart}
            className={`w-full px-4 py-2 rounded-md text-sm font-medium transition-colors ${
              canStart
                ? 'bg-blue-600 text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2'
                : 'bg-gray-300 text-gray-500 cursor-not-allowed'
            }`}
          >
            {isLoading ? (
              <span className="flex items-center justify-center">
                <svg
                  className="animate-spin -ml-1 mr-2 h-4 w-4 text-white"
                  fill="none"
                  viewBox="0 0 24 24"
                >
                  <circle
                    className="opacity-25"
                    cx="12"
                    cy="12"
                    r="10"
                    stroke="currentColor"
                    strokeWidth="4"
                  />
                  <path
                    className="opacity-75"
                    fill="currentColor"
                    d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
                  />
                </svg>
                Traitement...
              </span>
            ) : (
              'Démarrer la simulation'
            )}
          </button>

          {/* Stop button */}
          <button
            onClick={stopSimulation}
            disabled={!canStop}
            className={`w-full px-4 py-2 rounded-md text-sm font-medium transition-colors ${
              canStop
                ? 'bg-red-600 text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2'
                : 'bg-gray-300 text-gray-500 cursor-not-allowed'
            }`}
          >
            Arrêter la simulation
          </button>

          {/* Clear results button */}
          <button
            onClick={clearResults}
            disabled={!canClear}
            className={`w-full px-4 py-2 rounded-md text-sm font-medium transition-colors ${
              canClear
                ? 'bg-yellow-600 text-white hover:bg-yellow-700 focus:outline-none focus:ring-2 focus:ring-yellow-500 focus:ring-offset-2'
                : 'bg-gray-300 text-gray-500 cursor-not-allowed'
            }`}
          >
            Effacer les résultats
          </button>

          {/* Reset button */}
          <button
            onClick={reset}
            disabled={isRunning}
            className={`w-full px-4 py-2 rounded-md text-sm font-medium border transition-colors ${
              isRunning
                ? 'border-gray-300 text-gray-500 cursor-not-allowed'
                : 'border-gray-300 text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2'
            }`}
          >
            Réinitialiser
          </button>
        </div>

        {/* Simulation info */}
        {config && (
          <div className="mt-4 pt-4 border-t border-gray-200">
            <h4 className="text-xs font-medium text-gray-500 uppercase mb-2">
              Paramètres de simulation
            </h4>
            <div className="space-y-1 text-sm text-gray-600">
              <div className="flex justify-between">
                <span>Temps de préchauffage:</span>
                <span className="font-mono">{config.warmup_time?.toLocaleString()} unités</span>
              </div>
              <div className="flex justify-between">
                <span>Durée de simulation:</span>
                <span className="font-mono">{config.simulation_time?.toLocaleString()} unités</span>
              </div>
              {config.random_seed !== undefined && (
                <div className="flex justify-between">
                  <span>Graine aléatoire:</span>
                  <span className="font-mono">{config.random_seed}</span>
                </div>
              )}
            </div>
          </div>
        )}
      </div>
    </div>
  );
}