215 lines
6.2 KiB
TypeScript
215 lines
6.2 KiB
TypeScript
|
|
import React, { useState, useEffect } from "react";
|
|||
|
|
import {
|
|||
|
|
FaTimes,
|
|||
|
|
FaPlay,
|
|||
|
|
FaCheckCircle,
|
|||
|
|
FaSpinner,
|
|||
|
|
FaClipboardList,
|
|||
|
|
FaCalculator,
|
|||
|
|
FaBullseye,
|
|||
|
|
} from "react-icons/fa";
|
|||
|
|
|
|||
|
|
interface RunMrpModalProps {
|
|||
|
|
isOpen: boolean;
|
|||
|
|
onClose: () => void;
|
|||
|
|
onRunComplete: () => void;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
type Step =
|
|||
|
|
| "idle"
|
|||
|
|
| "demand"
|
|||
|
|
| "inventory"
|
|||
|
|
| "suggestions"
|
|||
|
|
| "completed"
|
|||
|
|
| "error";
|
|||
|
|
|
|||
|
|
const RunMrpModal: React.FC<RunMrpModalProps> = ({
|
|||
|
|
isOpen,
|
|||
|
|
onClose,
|
|||
|
|
onRunComplete,
|
|||
|
|
}) => {
|
|||
|
|
const [currentStep, setCurrentStep] = useState<Step>("idle");
|
|||
|
|
const [progress, setProgress] = useState(0);
|
|||
|
|
|
|||
|
|
useEffect(() => {
|
|||
|
|
if (currentStep !== "idle" && currentStep !== "completed") {
|
|||
|
|
const interval = setInterval(() => {
|
|||
|
|
setProgress((prev) => {
|
|||
|
|
if (prev >= 100) {
|
|||
|
|
clearInterval(interval);
|
|||
|
|
return 100;
|
|||
|
|
}
|
|||
|
|
return prev + 10;
|
|||
|
|
});
|
|||
|
|
}, 150);
|
|||
|
|
return () => clearInterval(interval);
|
|||
|
|
}
|
|||
|
|
}, [currentStep]);
|
|||
|
|
|
|||
|
|
useEffect(() => {
|
|||
|
|
if (progress >= 100) {
|
|||
|
|
if (currentStep === "demand") {
|
|||
|
|
setCurrentStep("inventory");
|
|||
|
|
setProgress(0);
|
|||
|
|
} else if (currentStep === "inventory") {
|
|||
|
|
setCurrentStep("suggestions");
|
|||
|
|
setProgress(0);
|
|||
|
|
} else if (currentStep === "suggestions") {
|
|||
|
|
onRunComplete(); // Signal completion to parent
|
|||
|
|
setCurrentStep("completed");
|
|||
|
|
setProgress(100);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}, [progress, currentStep, onRunComplete]);
|
|||
|
|
|
|||
|
|
const handleStartMrp = () => {
|
|||
|
|
setCurrentStep("demand");
|
|||
|
|
setProgress(0);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const handleClose = () => {
|
|||
|
|
setCurrentStep("idle");
|
|||
|
|
setProgress(0);
|
|||
|
|
onClose();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
if (!isOpen) return null;
|
|||
|
|
|
|||
|
|
const getStepClass = (step: Step, targetStep: Step) => {
|
|||
|
|
if (currentStep === step) return "text-blue-600 font-semibold";
|
|||
|
|
if (
|
|||
|
|
(targetStep === "demand" && currentStep !== "idle") ||
|
|||
|
|
(targetStep === "inventory" &&
|
|||
|
|
(currentStep === "suggestions" || currentStep === "completed")) ||
|
|||
|
|
(targetStep === "suggestions" && currentStep === "completed")
|
|||
|
|
) {
|
|||
|
|
return "text-green-600";
|
|||
|
|
}
|
|||
|
|
return "text-gray-500";
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const renderStep = (
|
|||
|
|
step: Step,
|
|||
|
|
targetStep: Step,
|
|||
|
|
icon: React.ReactNode,
|
|||
|
|
label: string
|
|||
|
|
) => (
|
|||
|
|
<div className="flex items-center gap-4">
|
|||
|
|
<div
|
|||
|
|
className={`p-3 rounded-full ${
|
|||
|
|
currentStep === step
|
|||
|
|
? "bg-blue-100"
|
|||
|
|
: getStepClass(step, targetStep) === "text-green-600"
|
|||
|
|
? "bg-green-100"
|
|||
|
|
: "bg-gray-100"
|
|||
|
|
}`}
|
|||
|
|
>
|
|||
|
|
{currentStep === step ? (
|
|||
|
|
<FaSpinner
|
|||
|
|
className={`w-6 h-6 animate-spin ${getStepClass(step, targetStep)}`}
|
|||
|
|
/>
|
|||
|
|
) : getStepClass(step, targetStep) === "text-green-600" ? (
|
|||
|
|
<FaCheckCircle
|
|||
|
|
className={`w-6 h-6 ${getStepClass(step, targetStep)}`}
|
|||
|
|
/>
|
|||
|
|
) : (
|
|||
|
|
icon
|
|||
|
|
)}
|
|||
|
|
</div>
|
|||
|
|
<div className="flex-1">
|
|||
|
|
<h4 className={`text-lg ${getStepClass(step, targetStep)}`}>{label}</h4>
|
|||
|
|
{currentStep === step && (
|
|||
|
|
<div className="w-full bg-gray-200 rounded-full h-2.5 mt-2">
|
|||
|
|
<div
|
|||
|
|
className="bg-blue-600 h-2.5 rounded-full transition-all duration-150"
|
|||
|
|
style={{ width: `${progress}%` }}
|
|||
|
|
></div>
|
|||
|
|
</div>
|
|||
|
|
)}
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
|
|||
|
|
<div className="bg-white rounded-lg shadow-xl max-w-lg w-full mx-4">
|
|||
|
|
<div className="flex items-center justify-between p-6 border-b">
|
|||
|
|
<h2 className="text-xl font-semibold text-gray-900">
|
|||
|
|
MRP Çalıştırma Süreci
|
|||
|
|
</h2>
|
|||
|
|
<button
|
|||
|
|
onClick={handleClose}
|
|||
|
|
className="text-gray-400 hover:text-gray-600"
|
|||
|
|
>
|
|||
|
|
<FaTimes className="w-5 h-5" />
|
|||
|
|
</button>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div className="p-6 space-y-6">
|
|||
|
|
{currentStep === "idle" && (
|
|||
|
|
<div className="text-center">
|
|||
|
|
<p className="text-gray-600 mb-6">
|
|||
|
|
MRP sürecini başlatmak için butona tıklayın. Bu işlem mevcut
|
|||
|
|
ihtiyaç ve önerileri güncelleyecektir.
|
|||
|
|
</p>
|
|||
|
|
<button
|
|||
|
|
onClick={handleStartMrp}
|
|||
|
|
className="flex items-center justify-center gap-2 w-full px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors text-base font-semibold"
|
|||
|
|
>
|
|||
|
|
<FaPlay />
|
|||
|
|
MRP Çalıştır
|
|||
|
|
</button>
|
|||
|
|
</div>
|
|||
|
|
)}
|
|||
|
|
|
|||
|
|
{currentStep !== "idle" && (
|
|||
|
|
<>
|
|||
|
|
{renderStep(
|
|||
|
|
"demand",
|
|||
|
|
"demand",
|
|||
|
|
<FaClipboardList className="w-6 h-6 text-gray-500" />,
|
|||
|
|
"Talep Toplama"
|
|||
|
|
)}
|
|||
|
|
{renderStep(
|
|||
|
|
"inventory",
|
|||
|
|
"demand",
|
|||
|
|
<FaCalculator className="w-6 h-6 text-gray-500" />,
|
|||
|
|
"Stok Kontrolü ve Net İhtiyaç Hesaplama"
|
|||
|
|
)}
|
|||
|
|
{renderStep(
|
|||
|
|
"suggestions",
|
|||
|
|
"inventory",
|
|||
|
|
<FaBullseye className="w-6 h-6 text-gray-500" />,
|
|||
|
|
"Üretim ve Satınalma Önerileri Oluşturma"
|
|||
|
|
)}
|
|||
|
|
</>
|
|||
|
|
)}
|
|||
|
|
|
|||
|
|
{currentStep === "completed" && (
|
|||
|
|
<div className="text-center p-6 bg-green-50 border border-green-200 rounded-lg">
|
|||
|
|
<FaCheckCircle className="w-12 h-12 text-green-600 mx-auto mb-4" />
|
|||
|
|
<h3 className="text-xl font-bold text-green-800">
|
|||
|
|
MRP Süreci Başarıyla Tamamlandı!
|
|||
|
|
</h3>
|
|||
|
|
<p className="text-green-700 mt-2">
|
|||
|
|
İlgili sayfalara giderek sonuçları inceleyebilirsiniz.
|
|||
|
|
</p>
|
|||
|
|
</div>
|
|||
|
|
)}
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div className="flex justify-end p-6 border-t">
|
|||
|
|
<button
|
|||
|
|
onClick={handleClose}
|
|||
|
|
className="px-3 py-1.5 bg-gray-600 text-white rounded-md hover:bg-gray-700 transition-colors text-sm"
|
|||
|
|
>
|
|||
|
|
Kapat
|
|||
|
|
</button>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
export default RunMrpModal;
|