Add guided wash flow to MyWashStart.vue with step-by-step instructions, brush details, and improved user navigation
This commit is contained in:
@@ -21,6 +21,7 @@ import WhiteBoxCard from "@/components/displays/boxes/WhiteBoxCard.vue";
|
||||
|
||||
import {getDepartmentsGuest} from "@/components/pagination/departmentTabs.vue";
|
||||
import {computed, onMounted, onUnmounted, ref, watch} from "vue";
|
||||
import ColorIndicator from "@/components/displays/buttons/ColorIndicator.vue";
|
||||
|
||||
const guestDepartments = ref([]);
|
||||
|
||||
@@ -210,6 +211,11 @@ const formattedElapsed = computed(() => {
|
||||
const totalSeconds = Math.floor(timeSinceWashStart.value / 1000);
|
||||
const minutes = Math.floor(totalSeconds / 60);
|
||||
const seconds = totalSeconds % 60;
|
||||
// If the elapsed time is negative, return 00:00
|
||||
if (minutes < 0 || seconds < 0) {
|
||||
return '00:00';
|
||||
}
|
||||
// Format as MM:SS
|
||||
return `${pad2(minutes)}:${pad2(seconds)}`;
|
||||
});
|
||||
const humanElapsed = computed(() => {
|
||||
@@ -495,6 +501,121 @@ watch(() => nearestDepartment.value, (newValue) => {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Guided wash flow
|
||||
*/
|
||||
const guidedWashFlow = ref(true);
|
||||
type guidedWashFlowBrushColor = 'is-black' | 'is-info' | 'is-link' | 'is-danger' | 'is-warning' | 'is-white';
|
||||
type guidedWashFlowBrushes = {
|
||||
label: string,
|
||||
description: string,
|
||||
warning?: string,
|
||||
color: guidedWashFlowBrushColor,
|
||||
position: 'left' | 'right',
|
||||
}[];
|
||||
type guidedWashFlowStep = {
|
||||
title: string,
|
||||
warning?: string,
|
||||
content: string,
|
||||
brushes: guidedWashFlowBrushes,
|
||||
}
|
||||
const guidedWashFlowSteps: guidedWashFlowStep[] = [
|
||||
{
|
||||
title: 'Højtryksforvask',
|
||||
content: '',
|
||||
warning: '',
|
||||
brushes: [
|
||||
{
|
||||
label: 'Sort slange',
|
||||
description: 'Spul med sort slange for at fjerne skidt.',
|
||||
warning: 'Min. afstand til bil 20cm.',
|
||||
color: 'is-black',
|
||||
position: 'right',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Sæbe-pålægning',
|
||||
content: 'Dæk bilen ind i sæbe',
|
||||
brushes: [
|
||||
{
|
||||
label: 'Blå børste',
|
||||
description: '',
|
||||
color: 'is-info',
|
||||
position: 'left',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Børstevask',
|
||||
content: 'Børst for at fjerne resterende snavs.',
|
||||
brushes: [
|
||||
{
|
||||
label: 'Blå børste',
|
||||
description: 'Bruges til lakerede overflader.',
|
||||
color: 'is-link',
|
||||
position: 'left',
|
||||
},
|
||||
{
|
||||
label: 'Rød børste',
|
||||
description: 'Bruges til undervogn og fælge.',
|
||||
color: 'is-danger',
|
||||
position: 'right',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Højtryksskylning',
|
||||
content: '',
|
||||
brushes: [
|
||||
{
|
||||
label: 'Sort slange',
|
||||
description: 'Spul med vand indtil sæben er væk.',
|
||||
color: 'is-black',
|
||||
position: 'right',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Voks pålægning',
|
||||
content: '',
|
||||
brushes: [
|
||||
{
|
||||
label: 'Gul slange',
|
||||
description: 'Påfør voks på førerhuset.',
|
||||
color: 'is-warning',
|
||||
position: 'left',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Spot Free skylning',
|
||||
content: '',
|
||||
brushes: [
|
||||
{
|
||||
label: 'Hvid slange',
|
||||
description: 'Skyl hurtigt førerhuset med Spot Free for at undgå pletter.',
|
||||
color: 'is-white',
|
||||
position: 'right',
|
||||
},
|
||||
],
|
||||
}
|
||||
];
|
||||
const currentGuidedWashStep = ref(0);
|
||||
const toggleGuidedWashFlow = () => {
|
||||
guidedWashFlow.value = !guidedWashFlow.value;
|
||||
};
|
||||
const nextGuidedWashStep = () => {
|
||||
if (currentGuidedWashStep.value < guidedWashFlowSteps.length - 1) {
|
||||
currentGuidedWashStep.value += 1;
|
||||
}
|
||||
};
|
||||
const previousGuidedWashStep = () => {
|
||||
if (currentGuidedWashStep.value > 0) {
|
||||
currentGuidedWashStep.value -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Watch for changes in the steps and update the localStorage accordingly.
|
||||
*/
|
||||
@@ -589,7 +710,7 @@ watch(() => currentStep.value, () => {
|
||||
<b-step-item label="Start vask" iconPack="fas" icon="droplet" :step="steps.SELECT_LANE" :clickable="clickableSteps[steps.SELECT_LANE]()">
|
||||
<h1 class="title has-text-centered">Start vask</h1>
|
||||
<b-field label="Vaskebane">
|
||||
<div class="columns is-multiline is-mobile is-centered">
|
||||
<div class="columns is-multiline is-mobile" :class="{ 'is-centered': nearestDepartment && (nearestDepartment.lanes || []).length >= 2 }">
|
||||
<template v-for="lane in nearestDepartment?.lanes || []" :key="lane">
|
||||
<div class="column is-half-mobile is-one-third-tablet is-one-quarter-desktop">
|
||||
<!-- Radio button for lane selection -->
|
||||
@@ -679,6 +800,73 @@ watch(() => currentStep.value, () => {
|
||||
<h2 class="subtitle has-text-centered">
|
||||
<strong>{{ formattedElapsed }}</strong>
|
||||
</h2>
|
||||
<template v-if="guidedWashFlow">
|
||||
<b-field label="Vasketrin">
|
||||
<b-steps type="is-link" size="is-small" v-model="currentGuidedWashStep">
|
||||
<b-step-item
|
||||
v-for="(step, index) in guidedWashFlowSteps"
|
||||
:key="index"
|
||||
:label="currentGuidedWashStep === index ? step.title : ''"
|
||||
:icon-pack="'fas'"
|
||||
:icon="index === currentGuidedWashStep ? 'brush' : 'soap'"
|
||||
:type="index === currentGuidedWashStep ? 'is-link' : 'is-light'"
|
||||
:step="index"
|
||||
>
|
||||
<h3 class="title is-5 has-text-centered">{{ step.title }}</h3>
|
||||
<!-- Warning -->
|
||||
<div v-if="step.warning" class="notification is-warning is-light has-text-centered">
|
||||
<span class="icon">
|
||||
<i class="fas fa-exclamation-triangle fa-lg"></i>
|
||||
</span>
|
||||
<span class="ml-2"><strong>{{ step.warning }}</strong></span>
|
||||
</div>
|
||||
<!-- Brushes -->
|
||||
<div class="columns is-centered">
|
||||
<div
|
||||
class="column is-narrow"
|
||||
v-for="(brush, bIndex) in step.brushes"
|
||||
:key="bIndex"
|
||||
>
|
||||
<div :class="['tag', 'is-medium', brush.color, 'mx-2', 'mb-0', 'mt-2']" style="display: flex; align-items: center; justify-content: center;">
|
||||
<span class="icon is-large">
|
||||
<i class="fas fa-droplet fa-lg"></i>
|
||||
</span>
|
||||
<span class="ml-1"><b>{{ brush.label }}</b></span>
|
||||
</div>
|
||||
<div class="is-block has-background-light p-2 mx-2" style="border-radius: 4px;">
|
||||
<p class="has-text-centered mt-1">{{ brush.description }}</p>
|
||||
</div>
|
||||
<div v-show="brush.warning"
|
||||
:class="['tag', 'is-medium', 'is-warning', 'mx-2', 'mb-0', 'mt-0']"
|
||||
style="display: flex; align-items: center; justify-content: center; border-top-left-radius: 0; border-top-right-radius: 0;">
|
||||
<span class="icon">
|
||||
<i class="fas fa-exclamation-triangle fa-lg"></i>
|
||||
</span>
|
||||
<span><strong>{{ brush.warning }}</strong></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="has-text-centered">{{ step.content }}</p>
|
||||
<div class="buttons is-centered">
|
||||
<b-button
|
||||
type="is-link is-light"
|
||||
icon-pack="fas"
|
||||
icon-left="arrow-left"
|
||||
:disabled="currentGuidedWashStep === 0"
|
||||
@click="previousGuidedWashStep"
|
||||
>Forrige</b-button>
|
||||
<b-button
|
||||
type="is-link"
|
||||
icon-pack="fas"
|
||||
icon-right="arrow-right"
|
||||
:disabled="currentGuidedWashStep === guidedWashFlowSteps.length - 1"
|
||||
@click="nextGuidedWashStep"
|
||||
>Næste</b-button>
|
||||
</div>
|
||||
</b-step-item>
|
||||
</b-steps>
|
||||
</b-field>
|
||||
</template>
|
||||
<p class="has-text-centered">
|
||||
Vasken er startet på bane {{ (currentLane && currentLane.name) ? currentLane.name : washLaneId }}.
|
||||
Når vasken er færdig, skal du trykke på knappen "Færdig" nedenfor for at afslutte processen.
|
||||
@@ -704,10 +892,11 @@ watch(() => currentStep.value, () => {
|
||||
<!--{{ currentStep }}-->
|
||||
<div class="buttons is-centered">
|
||||
<b-button
|
||||
v-show="currentStep !== steps.WASH_IN_PROGRESS && currentStep !== steps.COMPLETED"
|
||||
type="is-link is-light"
|
||||
icon-pack="fas"
|
||||
icon-left="arrow-left"
|
||||
:disabled="previous.disabled || currentStep === steps.COMPLETED"
|
||||
:disabled="previous.disabled || currentStep === steps.COMPLETED || currentStep === steps.WASH_IN_PROGRESS"
|
||||
@click.prevent="previous.action"
|
||||
>
|
||||
Forrige
|
||||
@@ -743,6 +932,14 @@ watch(() => currentStep.value, () => {
|
||||
:disabled="isNextButtonDisabled()"
|
||||
@click="() => onStartWash(radioLaneOption, licensePlateInput, customerNumberInput)"
|
||||
>Bekræft</b-button>
|
||||
<!-- Guided wash button -->
|
||||
<b-button
|
||||
v-show="currentStep === steps.WASH_IN_PROGRESS"
|
||||
type="is-link is-light"
|
||||
icon-pack="fas"
|
||||
icon-right="info-circle"
|
||||
@click.prevent="toggleGuidedWashFlow"
|
||||
>Vejledning</b-button>
|
||||
<!-- Complete button -->
|
||||
<b-button
|
||||
v-show="currentStep === steps.WASH_IN_PROGRESS"
|
||||
|
||||
Reference in New Issue
Block a user