Files
pleno-vue/src/composables/useWashFlowState.js
T

192 lines
5.3 KiB
JavaScript

export const WASH_STEPS = {
VEHICLE: 0,
QUESTIONS: 1,
SELECT_LANE: 2,
TASKS: 3,
WASH_IN_PROGRESS: 4,
COMPLETED: 5,
};
const normalizeLaneId = (value) => {
const normalized = parseInt(String(value ?? ""), 10);
return Number.isNaN(normalized) || normalized <= 0 ? null : normalized;
};
export function useWashFlowState(options) {
const {
currentStep,
washInProgress,
customerNumberInput,
licensePlateInput,
vehicleTypeSelect,
isCustomerNumberRequired,
radioLaneOption,
nearestDepartment,
allVisibleQuestionsAnswered,
isLoadingSelfServeData,
activeTasks,
completedTasks,
editAnswers,
isLaneAvailable,
isMachineAvailable,
onStartWash,
updateLaneAllowedServices,
} = options;
const steps = WASH_STEPS;
const targetStepForStart = () => (
activeTasks.value.length > 0 ? steps.TASKS : steps.WASH_IN_PROGRESS
);
const getSelectedLaneId = () => normalizeLaneId(radioLaneOption.value);
const getSelectedLane = () => {
const selectedLaneId = getSelectedLaneId();
if (selectedLaneId === null) {
return null;
}
return nearestDepartment.value?.lanes.find((lane) => normalizeLaneId(lane.id) === selectedLaneId) || null;
};
const clickableSteps = {
[steps.VEHICLE]: () => {
if (washInProgress.value) {
return currentStep.value === steps.VEHICLE;
}
const selectedVehicleTypeId = vehicleTypeSelect.value;
const hasSelectedVehicleType = selectedVehicleTypeId !== null && selectedVehicleTypeId !== undefined;
const customerNumberValue = customerNumberInput.value;
const requiresCustomerNumber = isCustomerNumberRequired?.value ?? false;
const customerNumberValid = !requiresCustomerNumber
|| customerNumberValue === null
|| customerNumberValue === undefined
|| String(customerNumberValue).trim() !== "";
const licensePlateValid = !!(licensePlateInput.value && licensePlateInput.value.trim() !== "");
if (!hasSelectedVehicleType) {
return false;
}
return customerNumberValid && licensePlateValid;
},
[steps.QUESTIONS]: () => {
if (washInProgress.value && currentStep.value >= steps.TASKS) {
return true;
}
if (washInProgress.value) {
return currentStep.value === steps.QUESTIONS;
}
return !!(licensePlateInput.value && licensePlateInput.value.trim() !== "") && !!vehicleTypeSelect.value;
},
[steps.SELECT_LANE]: () => {
if (washInProgress.value) {
return currentStep.value === steps.SELECT_LANE;
}
return (
!!(licensePlateInput.value && licensePlateInput.value.trim() !== "")
&& !!vehicleTypeSelect.value
&& allVisibleQuestionsAnswered.value
&& currentStep.value > steps.QUESTIONS
);
},
[steps.TASKS]: () => {
if (washInProgress.value && currentStep.value === steps.WASH_IN_PROGRESS) {
return true;
}
if (washInProgress.value) {
return currentStep.value === steps.TASKS;
}
return (
!!(licensePlateInput.value && licensePlateInput.value.trim() !== "")
&& !!vehicleTypeSelect.value
&& !!radioLaneOption.value
&& allVisibleQuestionsAnswered.value
&& currentStep.value >= steps.SELECT_LANE
);
},
[steps.WASH_IN_PROGRESS]: () => washInProgress.value,
};
const isNextButtonDisabled = () => {
if (currentStep.value === steps.VEHICLE) {
return !clickableSteps[steps.VEHICLE]();
}
if (currentStep.value === steps.SELECT_LANE) {
const selectedLane = getSelectedLane();
if (!selectedLane || !isLaneAvailable(selectedLane)) {
return true;
}
return radioLaneOption.value && currentStep.value === steps.SELECT_LANE
? (options.radioWashType.value === "Machine" && !isMachineAvailable(radioLaneOption.value))
: false;
}
if (currentStep.value === steps.QUESTIONS) {
if (isLoadingSelfServeData.value) {
return true;
}
return !allVisibleQuestionsAnswered.value;
}
if (currentStep.value === steps.TASKS) {
if (washInProgress.value) {
return activeTasks.value.some((task) => !completedTasks.value[task.id]);
}
return false;
}
return false;
};
const handleConfirmNext = async () => {
if (currentStep.value === steps.QUESTIONS) {
editAnswers.value = false;
const selectedLaneId = getSelectedLaneId();
if (selectedLaneId !== null) {
try {
await updateLaneAllowedServices(selectedLaneId);
} catch {
return;
}
}
currentStep.value = steps.SELECT_LANE;
return;
}
if (currentStep.value === steps.SELECT_LANE) {
if (washInProgress.value) {
currentStep.value = targetStepForStart();
return;
}
const selectedLaneId = getSelectedLaneId() ?? radioLaneOption.value;
await onStartWash(
selectedLaneId,
licensePlateInput.value,
customerNumberInput.value,
targetStepForStart()
);
return;
}
if (currentStep.value === steps.TASKS) {
currentStep.value = steps.WASH_IN_PROGRESS;
}
};
return {
steps,
clickableSteps,
isNextButtonDisabled,
handleConfirmNext,
targetStepForStart,
};
}